aboutsummaryrefslogtreecommitdiffstats
path: root/sm/server.c
diff options
context:
space:
mode:
Diffstat (limited to 'sm/server.c')
-rw-r--r--sm/server.c395
1 files changed, 233 insertions, 162 deletions
diff --git a/sm/server.c b/sm/server.c
index b88dc69e9..20cfc48b8 100644
--- a/sm/server.c
+++ b/sm/server.c
@@ -27,9 +27,8 @@
#include <ctype.h>
#include <unistd.h>
-#include <assuan.h>
-
#include "gpgsm.h"
+#include <assuan.h>
#include "sysutils.h"
#define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t))
@@ -183,7 +182,7 @@ start_audit_session (ctrl_t ctrl)
}
-static int
+static gpg_error_t
option_handler (assuan_context_t ctx, const char *key, const char *value)
{
ctrl_t ctrl = assuan_get_pointer (ctx);
@@ -309,11 +308,13 @@ option_handler (assuan_context_t ctx, const char *key, const char *value)
}
-static void
-reset_notify (assuan_context_t ctx)
+static gpg_error_t
+reset_notify (assuan_context_t ctx, char *line)
{
ctrl_t ctrl = assuan_get_pointer (ctx);
+ (void) line;
+
gpgsm_release_certlist (ctrl->server_local->recplist);
gpgsm_release_certlist (ctrl->server_local->signerlist);
ctrl->server_local->recplist = NULL;
@@ -321,11 +322,12 @@ reset_notify (assuan_context_t ctx)
close_message_fd (ctrl);
assuan_close_input_fd (ctx);
assuan_close_output_fd (ctx);
+ return 0;
}
-static void
-input_notify (assuan_context_t ctx, const char *line)
+static gpg_error_t
+input_notify (assuan_context_t ctx, char *line)
{
ctrl_t ctrl = assuan_get_pointer (ctx);
@@ -340,10 +342,11 @@ input_notify (assuan_context_t ctx, const char *line)
;
else
ctrl->autodetect_encoding = 1;
+ return 0;
}
-static void
-output_notify (assuan_context_t ctx, const char *line)
+static gpg_error_t
+output_notify (assuan_context_t ctx, char *line)
{
ctrl_t ctrl = assuan_get_pointer (ctx);
@@ -353,22 +356,23 @@ output_notify (assuan_context_t ctx, const char *line)
ctrl->create_pem = 1;
else if (strstr (line, "--base64"))
ctrl->create_base64 = 1; /* just the raw output */
+ return 0;
}
-
-/* RECIPIENT <userID>
-
- Set the recipient for the encryption. <userID> should be the
- internal representation of the key; the server may accept any other
- way of specification [we will support this]. If this is a valid and
- trusted recipient the server does respond with OK, otherwise the
- return is an ERR with the reason why the recipient can't be used,
- the encryption will then not be done for this recipient. If the
- policy is not to encrypt at all if not all recipients are valid, the
- client has to take care of this. All RECIPIENT commands are
- cumulative until a RESET or an successful ENCRYPT command. */
-static int
+static const char hlp_recipient[] =
+ "RECIPIENT <userID>\n"
+ "\n"
+ "Set the recipient for the encryption. USERID shall be the\n"
+ "internal representation of the key; the server may accept any other\n"
+ "way of specification [we will support this]. If this is a valid and\n"
+ "trusted recipient the server does respond with OK, otherwise the\n"
+ "return is an ERR with the reason why the recipient can't be used,\n"
+ "the encryption will then not be done for this recipient. If the\n"
+ "policy is not to encrypt at all if not all recipients are valid, the\n"
+ "client has to take care of this. All RECIPIENT commands are\n"
+ "cumulative until a RESET or an successful ENCRYPT command.";
+static gpg_error_t
cmd_recipient (assuan_context_t ctx, char *line)
{
ctrl_t ctrl = assuan_get_pointer (ctx);
@@ -391,20 +395,22 @@ cmd_recipient (assuan_context_t ctx, char *line)
return rc;
}
-/* SIGNER <userID>
-
- Set the signer's keys for the signature creation. <userID> should
- be the internal representation of the key; the server may accept any
- other way of specification [we will support this]. If this is a
- valid and usable signing key the server does respond with OK,
- otherwise it returns an ERR with the reason why the key can't be
- used, the signing will then not be done for this key. If the policy
- is not to sign at all if not all signer keys are valid, the client
- has to take care of this. All SIGNER commands are cumulative until
- a RESET but they are *not* reset by an SIGN command becuase it can
- be expected that set of signers are used for more than one sign
- operation. */
-static int
+
+static const char hlp_signer[] =
+ "SIGNER <userID>\n"
+ "\n"
+ "Set the signer's keys for the signature creation. USERID should\n"
+ "be the internal representation of the key; the server may accept any\n"
+ "other way of specification [we will support this]. If this is a\n"
+ "valid and usable signing key the server does respond with OK,\n"
+ "otherwise it returns an ERR with the reason why the key can't be\n"
+ "used, the signing will then not be done for this key. If the policy\n"
+ "is not to sign at all if not all signer keys are valid, the client\n"
+ "has to take care of this. All SIGNER commands are cumulative until\n"
+ "a RESET but they are *not* reset by an SIGN command becuase it can\n"
+ "be expected that set of signers are used for more than one sign\n"
+ "operation.";
+static gpg_error_t
cmd_signer (assuan_context_t ctx, char *line)
{
ctrl_t ctrl = assuan_get_pointer (ctx);
@@ -425,20 +431,21 @@ cmd_signer (assuan_context_t ctx, char *line)
}
-/* ENCRYPT
-
- Do the actual encryption process. Takes the plaintext from the INPUT
- command, writes to the ciphertext to the file descriptor set with
- the OUTPUT command, take the recipients form all the recipients set
- so far. If this command fails the clients should try to delete all
- output currently done or otherwise mark it as invalid. GPGSM does
- ensure that there won't be any security problem with leftover data
- on the output in this case.
-
- This command should in general not fail, as all necessary checks
- have been done while setting the recipients. The input and output
- pipes are closed. */
-static int
+static const char hlp_encrypt[] =
+ "ENCRYPT \n"
+ "\n"
+ "Do the actual encryption process. Takes the plaintext from the INPUT\n"
+ "command, writes to the ciphertext to the file descriptor set with\n"
+ "the OUTPUT command, take the recipients form all the recipients set\n"
+ "so far. If this command fails the clients should try to delete all\n"
+ "output currently done or otherwise mark it as invalid. GPGSM does\n"
+ "ensure that there won't be any security problem with leftover data\n"
+ "on the output in this case.\n"
+ "\n"
+ "This command should in general not fail, as all necessary checks\n"
+ "have been done while setting the recipients. The input and output\n"
+ "pipes are closed.";
+static gpg_error_t
cmd_encrypt (assuan_context_t ctx, char *line)
{
ctrl_t ctrl = assuan_get_pointer (ctx);
@@ -488,14 +495,15 @@ cmd_encrypt (assuan_context_t ctx, char *line)
}
-/* DECRYPT
-
- This performs the decrypt operation after doing some check on the
- internal state. (e.g. that only needed data has been set). Because
- it utilizes the GPG-Agent for the session key decryption, there is
- no need to ask the client for a protecting passphrase - GpgAgent
- does take care of this by requesting this from the user. */
-static int
+static const char hlp_decrypt[] =
+ "DECRYPT\n"
+ "\n"
+ "This performs the decrypt operation after doing some check on the\n"
+ "internal state. (e.g. that only needed data has been set). Because\n"
+ "it utilizes the GPG-Agent for the session key decryption, there is\n"
+ "no need to ask the client for a protecting passphrase - GPG-Agent\n"
+ "does take care of this by requesting this from the user.";
+static gpg_error_t
cmd_decrypt (assuan_context_t ctx, char *line)
{
ctrl_t ctrl = assuan_get_pointer (ctx);
@@ -530,16 +538,16 @@ cmd_decrypt (assuan_context_t ctx, char *line)
}
-/* VERIFY
-
- This does a verify operation on the message send to the input-FD.
- The result is written out using status lines. If an output FD was
- given, the signed text will be written to that.
-
- If the signature is a detached one, the server will inquire about
- the signed material and the client must provide it.
- */
-static int
+static const char hlp_verify[] =
+ "VERIFY\n"
+ "\n"
+ "This does a verify operation on the message send to the input FD.\n"
+ "The result is written out using status lines. If an output FD was\n"
+ "given, the signed text will be written to that.\n"
+ "\n"
+ "If the signature is a detached one, the server will inquire about\n"
+ "the signed material and the client must provide it.";
+static gpg_error_t
cmd_verify (assuan_context_t ctx, char *line)
{
int rc;
@@ -576,12 +584,13 @@ cmd_verify (assuan_context_t ctx, char *line)
}
-/* SIGN [--detached]
-
- Sign the data set with the INPUT command and write it to the sink
- set by OUTPUT. With "--detached" specified, a detached signature is
- created (surprise). */
-static int
+static const char hlp_sign[] =
+ "SIGN [--detached]\n"
+ "\n"
+ "Sign the data set with the INPUT command and write it to the sink\n"
+ "set by OUTPUT. With \"--detached\", a detached signature is\n"
+ "created (surprise).";
+static gpg_error_t
cmd_sign (assuan_context_t ctx, char *line)
{
ctrl_t ctrl = assuan_get_pointer (ctx);
@@ -618,18 +627,19 @@ cmd_sign (assuan_context_t ctx, char *line)
}
-/* IMPORT [--re-import]
-
- Import the certificates read form the input-fd, return status
- message for each imported one. The import checks the validity of
- the certificate but not of the entire chain. It is possible to
- import expired certificates.
-
- With the option --re-import the input data is expected to a be a LF
- separated list of fingerprints. The command will re-import these
- certificates, meaning that they are made permanent by removing
- their ephemeral flag. */
-static int
+static const char hlp_import[] =
+ "IMPORT [--re-import]\n"
+ "\n"
+ "Import the certificates read form the input-fd, return status\n"
+ "message for each imported one. The import checks the validity of\n"
+ "the certificate but not of the entire chain. It is possible to\n"
+ "import expired certificates.\n"
+ "\n"
+ "With the option --re-import the input data is expected to a be a LF\n"
+ "separated list of fingerprints. The command will re-import these\n"
+ "certificates, meaning that they are made permanent by removing\n"
+ "their ephemeral flag.";
+static gpg_error_t
cmd_import (assuan_context_t ctx, char *line)
{
ctrl_t ctrl = assuan_get_pointer (ctx);
@@ -653,11 +663,15 @@ cmd_import (assuan_context_t ctx, char *line)
}
-/* EXPORT [--data [--armor|--base64]] [--] pattern
-
- */
-
-static int
+static const char hlp_export[] =
+ "EXPORT [--data [--armor|--base64]] [--] <pattern>\n"
+ "\n"
+ "Export the certificates selected by PATTERN. With --data the output\n"
+ "is returned using Assuan D lines; the default is to use the sink given\n"
+ "by the last \"OUTPUT\" command. The options --armor or --base64 encode \n"
+ "the output using the PEM respective a plain base-64 format; the default\n"
+ "is a binary format which is only suitable for a single certificate.";
+static gpg_error_t
cmd_export (assuan_context_t ctx, char *line)
{
ctrl_t ctrl = assuan_get_pointer (ctx);
@@ -743,7 +757,14 @@ cmd_export (assuan_context_t ctx, char *line)
}
-static int
+
+static const char hlp_delkeys[] =
+ "DELKEYS <patterns>\n"
+ "\n"
+ "Delete the certificates specified by PATTERNS. Each pattern shall be\n"
+ "a percent-plus escaped certificate specification. Usually a\n"
+ "fingerprint will be used for this.";
+static gpg_error_t
cmd_delkeys (assuan_context_t ctx, char *line)
{
ctrl_t ctrl = assuan_get_pointer (ctx);
@@ -787,11 +808,28 @@ cmd_delkeys (assuan_context_t ctx, char *line)
-/* MESSAGE FD=<n>
-
- Set the file descriptor to read a message which is used with
- detached signatures */
-static int
+static const char hlp_output[] =
+ "OUTPUT FD[=<n>]\n"
+ "\n"
+ "Set the file descriptor to write the output data to N. If N is not\n"
+ "given and the operating system supports file descriptor passing, the\n"
+ "file descriptor currently in flight will be used. See also the\n"
+ "\"INPUT\" and \"MESSAGE\" commands.";
+static const char hlp_input[] =
+ "INPUT FD[=<n>]\n"
+ "\n"
+ "Set the file descriptor to read the input data to N. If N is not\n"
+ "given and the operating system supports file descriptor passing, the\n"
+ "file descriptor currently in flight will be used. See also the\n"
+ "\"MESSAGE\" and \"OUTPUT\" commands.";
+static const char hlp_message[] =
+ "MESSAGE FD[=<n>]\n"
+ "\n"
+ "Set the file descriptor to read the message for a detached\n"
+ "signatures to N. If N is not given and the operating system\n"
+ "supports file descriptor passing, the file descriptor currently in\n"
+ "flight will be used. See also the \"INPUT\" and \"OUTPUT\" commands.";
+static gpg_error_t
cmd_message (assuan_context_t ctx, char *line)
{
int rc;
@@ -809,11 +847,36 @@ cmd_message (assuan_context_t ctx, char *line)
return 0;
}
-/* LISTKEYS [<patterns>]
- DUMPKEYS [<patterns>]
- LISTSECRETKEYS [<patterns>]
- DUMPSECRETKEYS [<patterns>]
-*/
+
+
+static const char hlp_listkeys[] =
+ "LISTKEYS [<patterns>]\n"
+ "LISTSECRETKEYS [<patterns>]\n"
+ "DUMPKEYS [<patterns>]\n"
+ "DUMPSECRETKEYS [<patterns>]\n"
+ "\n"
+ "List all certificates or only those specified by PATTERNS. Each\n"
+ "pattern shall be a percent-plus escaped certificate specification.\n"
+ "The \"SECRET\" versions of the command filter the output to include\n"
+ "only certificates where the secret key is available or a corresponding\n"
+ "smartcard has been registered. The \"DUMP\" versions of the command\n"
+ "are only useful for debugging. The output format is a percent escaped\n"
+ "colon delimited listing as described in the manual.\n"
+ "\n"
+ "These \"OPTION\" command keys effect the output::\n"
+ "\n"
+ " \"list-mode\" set to 0: List only local certificates (default).\n"
+ " 1: Ditto.\n"
+ " 2: List only external certificates.\n"
+ " 3: List local and external certificates.\n"
+ "\n"
+ " \"with-validation\" set to true: Validate each certificate.\n"
+ "\n"
+ " \"with-ephemeral-key\" set to true: Always include ephemeral\n"
+ " certificates.\n"
+ "\n"
+ " \"list-to-output\" set to true: Write output to the file descriptor\n"
+ " given by the last \"OUTPUT\" command.";
static int
do_listkeys (assuan_context_t ctx, char *line, int mode)
{
@@ -879,37 +942,38 @@ do_listkeys (assuan_context_t ctx, char *line, int mode)
return err;
}
-static int
+static gpg_error_t
cmd_listkeys (assuan_context_t ctx, char *line)
{
return do_listkeys (ctx, line, 3);
}
-static int
+static gpg_error_t
cmd_dumpkeys (assuan_context_t ctx, char *line)
{
return do_listkeys (ctx, line, 259);
}
-static int
+static gpg_error_t
cmd_listsecretkeys (assuan_context_t ctx, char *line)
{
return do_listkeys (ctx, line, 2);
}
-static int
+static gpg_error_t
cmd_dumpsecretkeys (assuan_context_t ctx, char *line)
{
return do_listkeys (ctx, line, 258);
}
-
-/* GENKEY
- Read the parameters in native format from the input fd and write a
- certificate request to the output.
- */
-static int
+
+static const char hlp_genkey[] =
+ "GENKEY\n"
+ "\n"
+ "Read the parameters in native format from the input fd and write a\n"
+ "certificate request to the output.";
+static gpg_error_t
cmd_genkey (assuan_context_t ctx, char *line)
{
ctrl_t ctrl = assuan_get_pointer (ctx);
@@ -949,17 +1013,15 @@ cmd_genkey (assuan_context_t ctx, char *line)
-/* GETAUDITLOG [--data] [--html]
-
- !!!WORK in PROGRESS!!!
-
- If --data is used, the output is send using D-lines and not to the
- source given by an OUTPUT command.
-
- If --html is used the output is formated as an XHTML block. This is
- designed to be incorporated into a HTML document.
- */
-static int
+static const char hlp_getauditlog[] =
+ "GETAUDITLOG [--data] [--html]\n"
+ "\n"
+ "If --data is used, the output is send using D-lines and not to the\n"
+ "file descriptor given by an OUTPUT command.\n"
+ "\n"
+ "If --html is used the output is formated as an XHTML block. This is\n"
+ "designed to be incorporated into a HTML document.";
+static gpg_error_t
cmd_getauditlog (assuan_context_t ctx, char *line)
{
ctrl_t ctrl = assuan_get_pointer (ctx);
@@ -1007,19 +1069,18 @@ cmd_getauditlog (assuan_context_t ctx, char *line)
}
-/* GETINFO <what>
-
- Multipurpose function to return a variety of information.
- Supported values for WHAT are:
-
- version - Return the version of the program.
- pid - Return the process id of the server.
- agent-check - Return success if the agent is running.
- cmd_has_option CMD OPT
- - Returns OK if the command CMD implements the option OPT.
-
- */
-static int
+static const char hlp_getinfo[] =
+ "GETINFO <what>\n"
+ "\n"
+ "Multipurpose function to return a variety of information.\n"
+ "Supported values for WHAT are:\n"
+ "\n"
+ " version - Return the version of the program.\n"
+ " pid - Return the process id of the server.\n"
+ " agent-check - Return success if the agent is running.\n"
+ " cmd_has_option CMD OPT\n"
+ " - Returns OK if the command CMD implements the option OPT.";
+static gpg_error_t
cmd_getinfo (assuan_context_t ctx, char *line)
{
int rc = 0;
@@ -1101,34 +1162,36 @@ register_commands (assuan_context_t ctx)
{
static struct {
const char *name;
- int (*handler)(assuan_context_t, char *line);
+ assuan_handler_t handler;
+ const char * const help;
} table[] = {
- { "RECIPIENT", cmd_recipient },
- { "SIGNER", cmd_signer },
- { "ENCRYPT", cmd_encrypt },
- { "DECRYPT", cmd_decrypt },
- { "VERIFY", cmd_verify },
- { "SIGN", cmd_sign },
- { "IMPORT", cmd_import },
- { "EXPORT", cmd_export },
- { "INPUT", NULL },
- { "OUTPUT", NULL },
- { "MESSAGE", cmd_message },
- { "LISTKEYS", cmd_listkeys },
- { "DUMPKEYS", cmd_dumpkeys },
- { "LISTSECRETKEYS",cmd_listsecretkeys },
- { "DUMPSECRETKEYS",cmd_dumpsecretkeys },
- { "GENKEY", cmd_genkey },
- { "DELKEYS", cmd_delkeys },
- { "GETAUDITLOG", cmd_getauditlog },
- { "GETINFO", cmd_getinfo },
+ { "RECIPIENT", cmd_recipient, hlp_recipient },
+ { "SIGNER", cmd_signer, hlp_signer },
+ { "ENCRYPT", cmd_encrypt, hlp_encrypt },
+ { "DECRYPT", cmd_decrypt, hlp_decrypt },
+ { "VERIFY", cmd_verify, hlp_verify },
+ { "SIGN", cmd_sign, hlp_sign },
+ { "IMPORT", cmd_import, hlp_import },
+ { "EXPORT", cmd_export, hlp_export },
+ { "INPUT", NULL, hlp_input },
+ { "OUTPUT", NULL, hlp_output },
+ { "MESSAGE", cmd_message, hlp_message },
+ { "LISTKEYS", cmd_listkeys, hlp_listkeys },
+ { "DUMPKEYS", cmd_dumpkeys, hlp_listkeys },
+ { "LISTSECRETKEYS",cmd_listsecretkeys, hlp_listkeys },
+ { "DUMPSECRETKEYS",cmd_dumpsecretkeys, hlp_listkeys },
+ { "GENKEY", cmd_genkey, hlp_genkey },
+ { "DELKEYS", cmd_delkeys, hlp_delkeys },
+ { "GETAUDITLOG", cmd_getauditlog, hlp_getauditlog },
+ { "GETINFO", cmd_getinfo, hlp_getinfo },
{ NULL }
};
int i, rc;
for (i=0; table[i].name; i++)
{
- rc = assuan_register_command (ctx, table[i].name, table[i].handler);
+ rc = assuan_register_command (ctx, table[i].name, table[i].handler,
+ table[i].help);
if (rc)
return rc;
}
@@ -1142,7 +1205,7 @@ void
gpgsm_server (certlist_t default_recplist)
{
int rc;
- int filedes[2];
+ assuan_fd_t filedes[2];
assuan_context_t ctx;
struct server_control_s ctrl;
static const char hello[] = ("GNU Privacy Guard's S/M server "
@@ -1154,9 +1217,17 @@ gpgsm_server (certlist_t default_recplist)
/* We use a pipe based server so that we can work from scripts.
assuan_init_pipe_server will automagically detect when we are
called with a socketpair and ignore FIELDES in this case. */
- filedes[0] = 0;
- filedes[1] = 1;
- rc = assuan_init_pipe_server (&ctx, filedes);
+ filedes[0] = assuan_fdopen (0);
+ filedes[1] = assuan_fdopen (1);
+ rc = assuan_new (&ctx);
+ if (rc)
+ {
+ log_error ("failed to allocate assuan context: %s\n",
+ gpg_strerror (rc));
+ gpgsm_exit (2);
+ }
+
+ rc = assuan_init_pipe_server (ctx, filedes);
if (rc)
{
log_error ("failed to initialize the server: %s\n",
@@ -1241,7 +1312,7 @@ gpgsm_server (certlist_t default_recplist)
audit_release (ctrl.audit);
ctrl.audit = NULL;
- assuan_deinit_server (ctx);
+ assuan_release (ctx);
}