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 2 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, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
35 #define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
38 /* The filepointer for status message used in non-server mode */
39 static FILE *statusfp
;
41 /* Data used to assuciate an Assuan context with local server data */
42 struct server_local_s
{
43 assuan_context_t assuan_ctx
;
47 int list_to_output
; /* Write keylistings to the output fd. */
49 certlist_t signerlist
;
50 certlist_t default_recplist
; /* As set by main() - don't release. */
55 /* Note that it is sufficient to allocate the target string D as
56 long as the source string S, i.e.: strlen(s)+1; */
58 strcpy_escaped_plus (char *d
, const char *s
)
62 if (*s
== '%' && s
[1] && s
[2])
78 Blanks after the options are also removed. */
80 skip_options (const char *line
)
84 while ( *line
== '-' && line
[1] == '-' )
86 while (*line
&& !spacep (line
))
95 /* Check whether the option NAME appears in LINE */
97 has_option (const char *line
, const char *name
)
100 int n
= strlen (name
);
102 s
= strstr (line
, name
);
103 if (s
&& s
>= skip_options (line
))
105 return (s
&& (s
== line
|| spacep (s
-1)) && (!s
[n
] || spacep (s
+n
)));
110 close_message_fd (ctrl_t ctrl
)
112 if (ctrl
->server_local
->message_fd
!= -1)
114 close (ctrl
->server_local
->message_fd
);
115 ctrl
->server_local
->message_fd
= -1;
121 option_handler (assuan_context_t ctx
, const char *key
, const char *value
)
123 ctrl_t ctrl
= assuan_get_pointer (ctx
);
125 if (!strcmp (key
, "include-certs"))
127 int i
= *value
? atoi (value
) : -1;
128 if (ctrl
->include_certs
< -2)
129 return gpg_error (GPG_ERR_ASS_PARAMETER
);
130 ctrl
->include_certs
= i
;
132 else if (!strcmp (key
, "display"))
136 opt
.display
= strdup (value
);
138 return out_of_core ();
140 else if (!strcmp (key
, "ttyname"))
144 opt
.ttyname
= strdup (value
);
146 return out_of_core ();
148 else if (!strcmp (key
, "ttytype"))
152 opt
.ttytype
= strdup (value
);
154 return out_of_core ();
156 else if (!strcmp (key
, "lc-ctype"))
160 opt
.lc_ctype
= strdup (value
);
162 return out_of_core ();
164 else if (!strcmp (key
, "lc-messages"))
167 free (opt
.lc_messages
);
168 opt
.lc_messages
= strdup (value
);
169 if (!opt
.lc_messages
)
170 return out_of_core ();
172 else if (!strcmp (key
, "list-mode"))
174 int i
= *value
? atoi (value
) : 0;
175 if (!i
|| i
== 1) /* default and mode 1 */
177 ctrl
->server_local
->list_internal
= 1;
178 ctrl
->server_local
->list_external
= 0;
182 ctrl
->server_local
->list_internal
= 0;
183 ctrl
->server_local
->list_external
= 1;
187 ctrl
->server_local
->list_internal
= 1;
188 ctrl
->server_local
->list_external
= 1;
191 return gpg_error (GPG_ERR_ASS_PARAMETER
);
193 else if (!strcmp (key
, "list-to-output"))
195 int i
= *value
? atoi (value
) : 0;
196 ctrl
->server_local
->list_to_output
= i
;
198 else if (!strcmp (key
, "with-validation"))
200 int i
= *value
? atoi (value
) : 0;
201 ctrl
->with_validation
= i
;
203 else if (!strcmp (key
, "with-key-data"))
205 opt
.with_key_data
= 1;
208 return gpg_error (GPG_ERR_UNKNOWN_OPTION
);
217 reset_notify (assuan_context_t ctx
)
219 ctrl_t ctrl
= assuan_get_pointer (ctx
);
221 gpgsm_release_certlist (ctrl
->server_local
->recplist
);
222 gpgsm_release_certlist (ctrl
->server_local
->signerlist
);
223 ctrl
->server_local
->recplist
= NULL
;
224 ctrl
->server_local
->signerlist
= NULL
;
225 close_message_fd (ctrl
);
226 assuan_close_input_fd (ctx
);
227 assuan_close_output_fd (ctx
);
232 input_notify (assuan_context_t ctx
, const char *line
)
234 ctrl_t ctrl
= assuan_get_pointer (ctx
);
236 ctrl
->autodetect_encoding
= 0;
239 if (strstr (line
, "--armor"))
241 else if (strstr (line
, "--base64"))
243 else if (strstr (line
, "--binary"))
246 ctrl
->autodetect_encoding
= 1;
250 output_notify (assuan_context_t ctx
, const char *line
)
252 ctrl_t ctrl
= assuan_get_pointer (ctx
);
254 ctrl
->create_pem
= 0;
255 ctrl
->create_base64
= 0;
256 if (strstr (line
, "--armor"))
257 ctrl
->create_pem
= 1;
258 else if (strstr (line
, "--base64"))
259 ctrl
->create_base64
= 1; /* just the raw output */
264 /* RECIPIENT <userID>
266 Set the recipient for the encryption. <userID> should be the
267 internal representation of the key; the server may accept any other
268 way of specification [we will support this]. If this is a valid and
269 trusted recipient the server does respond with OK, otherwise the
270 return is an ERR with the reason why the recipient can't be used,
271 the encryption will then not be done for this recipient. If the
272 policy is not to encrypt at all if not all recipients are valid, the
273 client has to take care of this. All RECIPIENT commands are
274 cumulative until a RESET or an successful ENCRYPT command. */
276 cmd_recipient (assuan_context_t ctx
, char *line
)
278 ctrl_t ctrl
= assuan_get_pointer (ctx
);
281 rc
= gpgsm_add_to_certlist (ctrl
, line
, 0, &ctrl
->server_local
->recplist
, 0);
284 gpg_err_code_t r
= gpg_err_code (rc
);
285 gpgsm_status2 (ctrl
, STATUS_INV_RECP
,
287 r
== GPG_ERR_NO_PUBKEY
? "1":
288 r
== GPG_ERR_AMBIGUOUS_NAME
? "2":
289 r
== GPG_ERR_WRONG_KEY_USAGE
? "3":
290 r
== GPG_ERR_CERT_REVOKED
? "4":
291 r
== GPG_ERR_CERT_EXPIRED
? "5":
292 r
== GPG_ERR_NO_CRL_KNOWN
? "6":
293 r
== GPG_ERR_CRL_TOO_OLD
? "7":
294 r
== GPG_ERR_NO_POLICY_MATCH
? "8":
304 Set the signer's keys for the signature creation. <userID> should
305 be the internal representation of the key; the server may accept any
306 other way of specification [we will support this]. If this is a
307 valid and usable signing key the server does respond with OK,
308 otherwise it returns an ERR with the reason why the key can't be
309 used, the signing will then not be done for this key. If the policy
310 is not to sign at all if not all signer keys are valid, the client
311 has to take care of this. All SIGNER commands are cumulative until
312 a RESET but they are *not* reset by an SIGN command becuase it can
313 be expected that set of signers are used for more than one sign
316 Note that this command returns an INV_RECP status which is a bit
317 strange, but they are very similar. */
319 cmd_signer (assuan_context_t ctx
, char *line
)
321 ctrl_t ctrl
= assuan_get_pointer (ctx
);
324 rc
= gpgsm_add_to_certlist (ctrl
, line
, 1,
325 &ctrl
->server_local
->signerlist
, 0);
328 gpg_err_code_t r
= gpg_err_code (rc
);
329 gpgsm_status2 (ctrl
, STATUS_INV_RECP
,
331 r
== GPG_ERR_NO_PUBKEY
? "1":
332 r
== GPG_ERR_AMBIGUOUS_NAME
? "2":
333 r
== GPG_ERR_WRONG_KEY_USAGE
? "3":
334 r
== GPG_ERR_CERT_REVOKED
? "4":
335 r
== GPG_ERR_CERT_EXPIRED
? "5":
336 r
== GPG_ERR_NO_CRL_KNOWN
? "6":
337 r
== GPG_ERR_CRL_TOO_OLD
? "7":
338 r
== GPG_ERR_NO_POLICY_MATCH
? "8":
339 r
== GPG_ERR_NO_SECKEY
? "9":
349 Do the actual encryption process. Takes the plaintext from the INPUT
350 command, writes to the ciphertext to the file descriptor set with
351 the OUTPUT command, take the recipients form all the recipients set
352 so far. If this command fails the clients should try to delete all
353 output currently done or otherwise mark it as invalid. GPGSM does
354 ensure that there won't be any security problem with leftover data
355 on the output in this case.
357 This command should in general not fail, as all necessary checks
358 have been done while setting the recipients. The input and output
361 cmd_encrypt (assuan_context_t ctx
, char *line
)
363 ctrl_t ctrl
= assuan_get_pointer (ctx
);
369 inp_fd
= assuan_get_input_fd (ctx
);
371 return set_error (GPG_ERR_ASS_NO_INPUT
, NULL
);
372 out_fd
= assuan_get_output_fd (ctx
);
374 return set_error (GPG_ERR_ASS_NO_OUTPUT
, NULL
);
376 out_fp
= fdopen ( dup(out_fd
), "w");
378 return set_error (GPG_ERR_ASS_GENERAL
, "fdopen() failed");
380 /* Now add all encrypt-to marked recipients from the default
383 if (!opt
.no_encrypt_to
)
385 for (cl
=ctrl
->server_local
->default_recplist
; !rc
&& cl
; cl
= cl
->next
)
386 if (cl
->is_encrypt_to
)
387 rc
= gpgsm_add_cert_to_certlist (ctrl
, cl
->cert
,
388 &ctrl
->server_local
->recplist
, 1);
391 rc
= gpgsm_encrypt (assuan_get_pointer (ctx
),
392 ctrl
->server_local
->recplist
,
396 gpgsm_release_certlist (ctrl
->server_local
->recplist
);
397 ctrl
->server_local
->recplist
= NULL
;
398 /* Close and reset the fd */
399 close_message_fd (ctrl
);
400 assuan_close_input_fd (ctx
);
401 assuan_close_output_fd (ctx
);
407 This performs the decrypt operation after doing some check on the
408 internal state. (e.g. that only needed data has been set). Because
409 it utilizes the GPG-Agent for the session key decryption, there is
410 no need to ask the client for a protecting passphrase - GpgAgent
411 does take care of this by requesting this from the user. */
413 cmd_decrypt (assuan_context_t ctx
, char *line
)
415 ctrl_t ctrl
= assuan_get_pointer (ctx
);
420 inp_fd
= assuan_get_input_fd (ctx
);
422 return set_error (GPG_ERR_ASS_NO_INPUT
, NULL
);
423 out_fd
= assuan_get_output_fd (ctx
);
425 return set_error (GPG_ERR_ASS_NO_OUTPUT
, NULL
);
427 out_fp
= fdopen ( dup(out_fd
), "w");
429 return set_error (GPG_ERR_ASS_GENERAL
, "fdopen() failed");
430 rc
= gpgsm_decrypt (ctrl
, inp_fd
, out_fp
);
433 /* close and reset the fd */
434 close_message_fd (ctrl
);
435 assuan_close_input_fd (ctx
);
436 assuan_close_output_fd (ctx
);
444 This does a verify operation on the message send to the input-FD.
445 The result is written out using status lines. If an output FD was
446 given, the signed text will be written to that.
448 If the signature is a detached one, the server will inquire about
449 the signed material and the client must provide it.
452 cmd_verify (assuan_context_t ctx
, char *line
)
455 ctrl_t ctrl
= assuan_get_pointer (ctx
);
456 int fd
= assuan_get_input_fd (ctx
);
457 int out_fd
= assuan_get_output_fd (ctx
);
461 return set_error (GPG_ERR_ASS_NO_INPUT
, NULL
);
465 out_fp
= fdopen ( dup(out_fd
), "w");
467 return set_error (GPG_ERR_ASS_GENERAL
, "fdopen() failed");
470 rc
= gpgsm_verify (assuan_get_pointer (ctx
), fd
,
471 ctrl
->server_local
->message_fd
, out_fp
);
475 /* close and reset the fd */
476 close_message_fd (ctrl
);
477 assuan_close_input_fd (ctx
);
478 assuan_close_output_fd (ctx
);
486 Sign the data set with the INPUT command and write it to the sink
487 set by OUTPUT. With "--detached" specified, a detached signature is
488 created (surprise). */
490 cmd_sign (assuan_context_t ctx
, char *line
)
492 ctrl_t ctrl
= assuan_get_pointer (ctx
);
498 inp_fd
= assuan_get_input_fd (ctx
);
500 return set_error (GPG_ERR_ASS_NO_INPUT
, NULL
);
501 out_fd
= assuan_get_output_fd (ctx
);
503 return set_error (GPG_ERR_ASS_NO_OUTPUT
, NULL
);
505 detached
= has_option (line
, "--detached");
507 out_fp
= fdopen ( dup(out_fd
), "w");
509 return set_error (GPG_ERR_ASS_GENERAL
, "fdopen() failed");
511 rc
= gpgsm_sign (assuan_get_pointer (ctx
), ctrl
->server_local
->signerlist
,
512 inp_fd
, detached
, out_fp
);
515 /* close and reset the fd */
516 close_message_fd (ctrl
);
517 assuan_close_input_fd (ctx
);
518 assuan_close_output_fd (ctx
);
526 Import the certificates read form the input-fd, return status
527 message for each imported one. The import checks the validity of
528 the certificate but not of the entire chain. It is possible to
529 import expired certificates. */
531 cmd_import (assuan_context_t ctx
, char *line
)
533 ctrl_t ctrl
= assuan_get_pointer (ctx
);
535 int fd
= assuan_get_input_fd (ctx
);
538 return set_error (GPG_ERR_ASS_NO_INPUT
, NULL
);
540 rc
= gpgsm_import (assuan_get_pointer (ctx
), fd
);
542 /* close and reset the fd */
543 close_message_fd (ctrl
);
544 assuan_close_input_fd (ctx
);
545 assuan_close_output_fd (ctx
);
551 /* EXPORT [--data [--armor|--base64]] [--] pattern
556 cmd_export (assuan_context_t ctx
, char *line
)
558 ctrl_t ctrl
= assuan_get_pointer (ctx
);
559 int fd
= assuan_get_output_fd (ctx
);
565 use_data
= has_option (line
, "--data");
569 /* We need to override any possible setting done by an OUTPUT command. */
570 ctrl
->create_pem
= has_option (line
, "--armor");
571 ctrl
->create_base64
= has_option (line
, "--base64");
574 line
= skip_options (line
);
576 /* Break the line down into an strlist_t. */
578 for (p
=line
; *p
; line
= p
)
580 while (*p
&& *p
!= ' ')
586 sl
= xtrymalloc (sizeof *sl
+ strlen (line
));
590 return out_of_core ();
593 strcpy_escaped_plus (sl
->d
, line
);
601 out_fp
= assuan_get_data_fp (ctx
);
605 return set_error (GPG_ERR_ASS_GENERAL
, "no data stream");
607 gpgsm_export (ctrl
, list
, out_fp
);
614 return set_error (GPG_ERR_ASS_NO_OUTPUT
, NULL
);
616 out_fp
= fdopen ( dup(fd
), "w");
620 return set_error (GPG_ERR_ASS_GENERAL
, "fdopen() failed");
623 gpgsm_export (ctrl
, list
, out_fp
);
628 /* Close and reset the fds. */
629 close_message_fd (ctrl
);
630 assuan_close_input_fd (ctx
);
631 assuan_close_output_fd (ctx
);
637 cmd_delkeys (assuan_context_t ctx
, char *line
)
639 ctrl_t ctrl
= assuan_get_pointer (ctx
);
644 /* break the line down into an strlist_t */
646 for (p
=line
; *p
; line
= p
)
648 while (*p
&& *p
!= ' ')
654 sl
= xtrymalloc (sizeof *sl
+ strlen (line
));
658 return out_of_core ();
661 strcpy_escaped_plus (sl
->d
, line
);
667 rc
= gpgsm_delete (ctrl
, list
);
670 /* close and reset the fd */
671 close_message_fd (ctrl
);
672 assuan_close_input_fd (ctx
);
673 assuan_close_output_fd (ctx
);
682 Set the file descriptor to read a message which is used with
683 detached signatures */
685 cmd_message (assuan_context_t ctx
, char *line
)
689 ctrl_t ctrl
= assuan_get_pointer (ctx
);
691 rc
= assuan_command_parse_fd (ctx
, line
, &fd
);
695 return set_error (GPG_ERR_ASS_NO_INPUT
, NULL
);
696 ctrl
->server_local
->message_fd
= fd
;
700 /* LISTKEYS [<patterns>]
701 DUMPKEYS [<patterns>]
702 LISTSECRETKEYS [<patterns>]
703 DUMPSECRETKEYS [<patterns>]
706 do_listkeys (assuan_context_t ctx
, char *line
, int mode
)
708 ctrl_t ctrl
= assuan_get_pointer (ctx
);
712 unsigned int listmode
;
715 /* Break the line down into an strlist. */
717 for (p
=line
; *p
; line
= p
)
719 while (*p
&& *p
!= ' ')
725 sl
= xtrymalloc (sizeof *sl
+ strlen (line
));
729 return out_of_core ();
732 strcpy_escaped_plus (sl
->d
, line
);
738 if (ctrl
->server_local
->list_to_output
)
740 if ( assuan_get_output_fd (ctx
) == -1 )
741 return set_error (GPG_ERR_ASS_NO_OUTPUT
, NULL
);
742 fp
= fdopen (assuan_get_output_fd (ctx
), "w");
744 return set_error (GPG_ERR_ASS_GENERAL
, "fdopen() failed");
748 fp
= assuan_get_data_fp (ctx
);
750 return set_error (GPG_ERR_ASS_GENERAL
, "no data stream");
753 ctrl
->with_colons
= 1;
755 if (ctrl
->server_local
->list_internal
)
757 if (ctrl
->server_local
->list_external
)
759 err
= gpgsm_list_keys (assuan_get_pointer (ctx
), list
, fp
, listmode
);
761 if (ctrl
->server_local
->list_to_output
)
764 assuan_close_output_fd (ctx
);
770 cmd_listkeys (assuan_context_t ctx
, char *line
)
772 return do_listkeys (ctx
, line
, 3);
776 cmd_dumpkeys (assuan_context_t ctx
, char *line
)
778 return do_listkeys (ctx
, line
, 259);
782 cmd_listsecretkeys (assuan_context_t ctx
, char *line
)
784 return do_listkeys (ctx
, line
, 2);
788 cmd_dumpsecretkeys (assuan_context_t ctx
, char *line
)
790 return do_listkeys (ctx
, line
, 258);
796 Read the parameters in native format from the input fd and write a
797 certificate request to the output.
800 cmd_genkey (assuan_context_t ctx
, char *line
)
802 ctrl_t ctrl
= assuan_get_pointer (ctx
);
807 inp_fd
= assuan_get_input_fd (ctx
);
809 return set_error (GPG_ERR_ASS_NO_INPUT
, NULL
);
810 out_fd
= assuan_get_output_fd (ctx
);
812 return set_error (GPG_ERR_ASS_NO_OUTPUT
, NULL
);
814 out_fp
= fdopen ( dup(out_fd
), "w");
816 return set_error (GPG_ERR_ASS_GENERAL
, "fdopen() failed");
817 rc
= gpgsm_genkey (ctrl
, inp_fd
, out_fp
);
820 /* close and reset the fds */
821 assuan_close_input_fd (ctx
);
822 assuan_close_output_fd (ctx
);
831 /* Tell the assuan library about our commands */
833 register_commands (assuan_context_t ctx
)
837 int (*handler
)(assuan_context_t
, char *line
);
839 { "RECIPIENT", cmd_recipient
},
840 { "SIGNER", cmd_signer
},
841 { "ENCRYPT", cmd_encrypt
},
842 { "DECRYPT", cmd_decrypt
},
843 { "VERIFY", cmd_verify
},
844 { "SIGN", cmd_sign
},
845 { "IMPORT", cmd_import
},
846 { "EXPORT", cmd_export
},
849 { "MESSAGE", cmd_message
},
850 { "LISTKEYS", cmd_listkeys
},
851 { "DUMPKEYS", cmd_dumpkeys
},
852 { "LISTSECRETKEYS",cmd_listsecretkeys
},
853 { "DUMPSECRETKEYS",cmd_dumpsecretkeys
},
854 { "GENKEY", cmd_genkey
},
855 { "DELKEYS", cmd_delkeys
},
860 for (i
=0; table
[i
].name
; i
++)
862 rc
= assuan_register_command (ctx
, table
[i
].name
, table
[i
].handler
);
869 /* Startup the server. DEFAULT_RECPLIST is the list of recipients as
870 set from the command line or config file. We only require those
871 marked as encrypt-to. */
873 gpgsm_server (certlist_t default_recplist
)
877 assuan_context_t ctx
;
878 struct server_control_s ctrl
;
879 static const char hello
[] = ("GNU Privacy Guard's S/M server "
882 memset (&ctrl
, 0, sizeof ctrl
);
883 gpgsm_init_default_ctrl (&ctrl
);
885 /* We use a pipe based server so that we can work from scripts.
886 assuan_init_pipe_server will automagically detect when we are
887 called with a socketpair and ignore FIELDES in this case. */
890 rc
= assuan_init_pipe_server (&ctx
, filedes
);
893 log_error ("failed to initialize the server: %s\n",
897 rc
= register_commands (ctx
);
900 log_error ("failed to the register commands with Assuan: %s\n",
904 if (opt
.verbose
|| opt
.debug
)
907 const char *s1
= getenv ("GPG_AGENT_INFO");
908 const char *s2
= getenv ("DIRMNGR_INFO");
922 assuan_set_hello_line (ctx
, tmp
);
927 assuan_set_hello_line (ctx
, hello
);
929 assuan_register_reset_notify (ctx
, reset_notify
);
930 assuan_register_input_notify (ctx
, input_notify
);
931 assuan_register_output_notify (ctx
, output_notify
);
932 assuan_register_option_handler (ctx
, option_handler
);
934 assuan_set_pointer (ctx
, &ctrl
);
935 ctrl
.server_local
= xcalloc (1, sizeof *ctrl
.server_local
);
936 ctrl
.server_local
->assuan_ctx
= ctx
;
937 ctrl
.server_local
->message_fd
= -1;
938 ctrl
.server_local
->list_internal
= 1;
939 ctrl
.server_local
->list_external
= 0;
940 ctrl
.server_local
->default_recplist
= default_recplist
;
943 assuan_set_log_stream (ctx
, log_get_stream ());
947 rc
= assuan_accept (ctx
);
954 log_info ("Assuan accept problem: %s\n", gpg_strerror (rc
));
958 rc
= assuan_process (ctx
);
961 log_info ("Assuan processing failed: %s\n", gpg_strerror (rc
));
966 gpgsm_release_certlist (ctrl
.server_local
->recplist
);
967 ctrl
.server_local
->recplist
= NULL
;
968 gpgsm_release_certlist (ctrl
.server_local
->signerlist
);
969 ctrl
.server_local
->signerlist
= NULL
;
970 xfree (ctrl
.server_local
);
972 assuan_deinit_server (ctx
);
977 get_status_string ( int no
)
983 case STATUS_ENTER
: s
= "ENTER"; break;
984 case STATUS_LEAVE
: s
= "LEAVE"; break;
985 case STATUS_ABORT
: s
= "ABORT"; break;
986 case STATUS_NEWSIG
: s
= "NEWSIG"; break;
987 case STATUS_GOODSIG
: s
= "GOODSIG"; break;
988 case STATUS_SIGEXPIRED
: s
= "SIGEXPIRED"; break;
989 case STATUS_KEYREVOKED
: s
= "KEYREVOKED"; break;
990 case STATUS_BADSIG
: s
= "BADSIG"; break;
991 case STATUS_ERRSIG
: s
= "ERRSIG"; break;
992 case STATUS_BADARMOR
: s
= "BADARMOR"; break;
993 case STATUS_RSA_OR_IDEA
: s
= "RSA_OR_IDEA"; break;
994 case STATUS_TRUST_UNDEFINED
: s
= "TRUST_UNDEFINED"; break;
995 case STATUS_TRUST_NEVER
: s
= "TRUST_NEVER"; break;
996 case STATUS_TRUST_MARGINAL
: s
= "TRUST_MARGINAL"; break;
997 case STATUS_TRUST_FULLY
: s
= "TRUST_FULLY"; break;
998 case STATUS_TRUST_ULTIMATE
: s
= "TRUST_ULTIMATE"; break;
999 case STATUS_GET_BOOL
: s
= "GET_BOOL"; break;
1000 case STATUS_GET_LINE
: s
= "GET_LINE"; break;
1001 case STATUS_GET_HIDDEN
: s
= "GET_HIDDEN"; break;
1002 case STATUS_GOT_IT
: s
= "GOT_IT"; break;
1003 case STATUS_SHM_INFO
: s
= "SHM_INFO"; break;
1004 case STATUS_SHM_GET
: s
= "SHM_GET"; break;
1005 case STATUS_SHM_GET_BOOL
: s
= "SHM_GET_BOOL"; break;
1006 case STATUS_SHM_GET_HIDDEN
: s
= "SHM_GET_HIDDEN"; break;
1007 case STATUS_NEED_PASSPHRASE
: s
= "NEED_PASSPHRASE"; break;
1008 case STATUS_VALIDSIG
: s
= "VALIDSIG"; break;
1009 case STATUS_SIG_ID
: s
= "SIG_ID"; break;
1010 case STATUS_ENC_TO
: s
= "ENC_TO"; break;
1011 case STATUS_NODATA
: s
= "NODATA"; break;
1012 case STATUS_BAD_PASSPHRASE
: s
= "BAD_PASSPHRASE"; break;
1013 case STATUS_NO_PUBKEY
: s
= "NO_PUBKEY"; break;
1014 case STATUS_NO_SECKEY
: s
= "NO_SECKEY"; break;
1015 case STATUS_NEED_PASSPHRASE_SYM
: s
= "NEED_PASSPHRASE_SYM"; break;
1016 case STATUS_DECRYPTION_FAILED
: s
= "DECRYPTION_FAILED"; break;
1017 case STATUS_DECRYPTION_OKAY
: s
= "DECRYPTION_OKAY"; break;
1018 case STATUS_MISSING_PASSPHRASE
: s
= "MISSING_PASSPHRASE"; break;
1019 case STATUS_GOOD_PASSPHRASE
: s
= "GOOD_PASSPHRASE"; break;
1020 case STATUS_GOODMDC
: s
= "GOODMDC"; break;
1021 case STATUS_BADMDC
: s
= "BADMDC"; break;
1022 case STATUS_ERRMDC
: s
= "ERRMDC"; break;
1023 case STATUS_IMPORTED
: s
= "IMPORTED"; break;
1024 case STATUS_IMPORT_OK
: s
= "IMPORT_OK"; break;
1025 case STATUS_IMPORT_RES
: s
= "IMPORT_RES"; break;
1026 case STATUS_FILE_START
: s
= "FILE_START"; break;
1027 case STATUS_FILE_DONE
: s
= "FILE_DONE"; break;
1028 case STATUS_FILE_ERROR
: s
= "FILE_ERROR"; break;
1029 case STATUS_BEGIN_DECRYPTION
:s
= "BEGIN_DECRYPTION"; break;
1030 case STATUS_END_DECRYPTION
: s
= "END_DECRYPTION"; break;
1031 case STATUS_BEGIN_ENCRYPTION
:s
= "BEGIN_ENCRYPTION"; break;
1032 case STATUS_END_ENCRYPTION
: s
= "END_ENCRYPTION"; break;
1033 case STATUS_DELETE_PROBLEM
: s
= "DELETE_PROBLEM"; break;
1034 case STATUS_PROGRESS
: s
= "PROGRESS"; break;
1035 case STATUS_SIG_CREATED
: s
= "SIG_CREATED"; break;
1036 case STATUS_SESSION_KEY
: s
= "SESSION_KEY"; break;
1037 case STATUS_NOTATION_NAME
: s
= "NOTATION_NAME" ; break;
1038 case STATUS_NOTATION_DATA
: s
= "NOTATION_DATA" ; break;
1039 case STATUS_POLICY_URL
: s
= "POLICY_URL" ; break;
1040 case STATUS_BEGIN_STREAM
: s
= "BEGIN_STREAM"; break;
1041 case STATUS_END_STREAM
: s
= "END_STREAM"; break;
1042 case STATUS_KEY_CREATED
: s
= "KEY_CREATED"; break;
1043 case STATUS_UNEXPECTED
: s
= "UNEXPECTED"; break;
1044 case STATUS_INV_RECP
: s
= "INV_RECP"; break;
1045 case STATUS_NO_RECP
: s
= "NO_RECP"; break;
1046 case STATUS_ALREADY_SIGNED
: s
= "ALREADY_SIGNED"; break;
1047 case STATUS_EXPSIG
: s
= "EXPSIG"; break;
1048 case STATUS_EXPKEYSIG
: s
= "EXPKEYSIG"; break;
1049 case STATUS_TRUNCATED
: s
= "TRUNCATED"; break;
1050 case STATUS_ERROR
: s
= "ERROR"; break;
1051 case STATUS_IMPORT_PROBLEM
: s
= "IMPORT_PROBLEM"; break;
1052 default: s
= "?"; break;
1059 gpgsm_status2 (ctrl_t ctrl
, int no
, ...)
1061 gpg_error_t err
= 0;
1065 va_start (arg_ptr
, no
);
1067 if (ctrl
->no_server
&& ctrl
->status_fd
== -1)
1068 ; /* No status wanted. */
1069 else if (ctrl
->no_server
)
1073 if (ctrl
->status_fd
== 1)
1075 else if (ctrl
->status_fd
== 2)
1078 statusfp
= fdopen (ctrl
->status_fd
, "w");
1082 log_fatal ("can't open fd %d for status output: %s\n",
1083 ctrl
->status_fd
, strerror(errno
));
1087 fputs ("[GNUPG:] ", statusfp
);
1088 fputs (get_status_string (no
), statusfp
);
1090 while ( (text
= va_arg (arg_ptr
, const char*) ))
1092 putc ( ' ', statusfp
);
1093 for (; *text
; text
++)
1096 fputs ( "\\n", statusfp
);
1097 else if (*text
== '\r')
1098 fputs ( "\\r", statusfp
);
1100 putc ( *(const byte
*)text
, statusfp
);
1103 putc ('\n', statusfp
);
1108 assuan_context_t ctx
= ctrl
->server_local
->assuan_ctx
;
1114 while ( (text
= va_arg (arg_ptr
, const char *)) )
1121 for ( ; *text
&& n
< DIM (buf
)-2; n
++)
1125 err
= assuan_write_status (ctx
, get_status_string (no
), buf
);
1133 gpgsm_status (ctrl_t ctrl
, int no
, const char *text
)
1135 return gpgsm_status2 (ctrl
, no
, text
, NULL
);
1139 gpgsm_status_with_err_code (ctrl_t ctrl
, int no
, const char *text
,
1144 sprintf (buf
, "%u", (unsigned int)ec
);
1146 return gpgsm_status2 (ctrl
, no
, text
, buf
, NULL
);
1148 return gpgsm_status2 (ctrl
, no
, buf
, NULL
);