diff options
author | Werner Koch <wk@gnupg.org> | 2009-10-15 19:20:41 +0200 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2009-10-15 19:20:41 +0200 |
commit | 598bf9199e89a53bc0ffd2e32141a42d5ec85184 (patch) | |
tree | 0a5d888558adc8f13d873bbf93c639f5aaebb738 /g13/server.c | |
parent | mount does now work in server and standalone mode. (diff) | |
download | gnupg2-598bf9199e89a53bc0ffd2e32141a42d5ec85184.tar.xz gnupg2-598bf9199e89a53bc0ffd2e32141a42d5ec85184.zip |
Reworked the server commands.
Track mounts.
--create does now work as expected.
Diffstat (limited to 'g13/server.c')
-rw-r--r-- | g13/server.c | 317 |
1 files changed, 176 insertions, 141 deletions
diff --git a/g13/server.c b/g13/server.c index bdf214f32..900dbc909 100644 --- a/g13/server.c +++ b/g13/server.c @@ -40,42 +40,28 @@ struct server_local_s /* The Assuan contect we are working on. */ assuan_context_t assuan_ctx; - char *mountpoint; /* Malloced current mountpoint. */ + char *containername; /* Malloced active containername. */ }; -/* Cookie definition for assuan data line output. */ -static ssize_t data_line_cookie_write (void *cookie, - const void *buffer, size_t size); -static int data_line_cookie_close (void *cookie); -static es_cookie_io_functions_t data_line_cookie_functions = - { - NULL, - data_line_cookie_write, - NULL, - data_line_cookie_close - }; - - -/* The filepointer for status message used in non-server mode. */ -/* static FILE *statusfp; FIXME; */ - - +/* Local prototypes. */ static int command_has_option (const char *cmd, const char *cmdopt); -#define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t)) +/* + Helper functions. + */ +/* Set an error and a description. */ +#define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t)) - -/* Skip over options. - Blanks after the options are also removed. */ +/* Skip over options. Blanks after the options are also removed. */ static char * skip_options (const char *line) { @@ -93,52 +79,41 @@ skip_options (const char *line) /* Check whether the option NAME appears in LINE. */ -static int -has_option (const char *line, const char *name) -{ - const char *s; - int n = strlen (name); +/* static int */ +/* has_option (const char *line, const char *name) */ +/* { */ +/* const char *s; */ +/* int n = strlen (name); */ - s = strstr (line, name); - if (s && s >= skip_options (line)) - return 0; - return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n))); -} +/* s = strstr (line, name); */ +/* if (s && s >= skip_options (line)) */ +/* return 0; */ +/* return (s && (s == line || spacep (s-1)) && (!s[n] || spacep (s+n))); */ +/* } */ -/* A write handler used by es_fopencookie to write Assuan data - lines. */ -static ssize_t -data_line_cookie_write (void *cookie, const void *buffer, size_t size) +/* Helper to print a message while leaving a command. */ +static gpg_error_t +leave_cmd (assuan_context_t ctx, gpg_error_t err) { - assuan_context_t ctx = cookie; - - if (assuan_send_data (ctx, buffer, size)) + if (err) { - errno = EIO; - return -1; + const char *name = assuan_get_command_name (ctx); + if (!name) + name = "?"; + if (gpg_err_source (err) == GPG_ERR_SOURCE_DEFAULT) + log_error ("command '%s' failed: %s\n", name, + gpg_strerror (err)); + else + log_error ("command '%s' failed: %s <%s>\n", name, + gpg_strerror (err), gpg_strsource (err)); } - - return size; + return err; } -/* A close handler used by es_fopencookie to write Assuan data - lines. */ -static int -data_line_cookie_close (void *cookie) -{ - assuan_context_t ctx = cookie; - - if (assuan_send_data (ctx, NULL, 0)) - { - errno = EIO; - return -1; - } - - return 0; -} + /* The handler for Assuan OPTION commands. */ static gpg_error_t option_handler (assuan_context_t ctx, const char *key, const char *value) @@ -146,6 +121,8 @@ option_handler (assuan_context_t ctx, const char *key, const char *value) ctrl_t ctrl = assuan_get_pointer (ctx); gpg_error_t err = 0; + (void)ctrl; + if (!strcmp (key, "putenv")) { /* Change the session's environment to be used for the @@ -213,84 +190,83 @@ reset_notify (assuan_context_t ctx) { ctrl_t ctrl = assuan_get_pointer (ctx); - xfree (ctrl->server_local->mountpoint); - ctrl->server_local->mountpoint = NULL; + xfree (ctrl->server_local->containername); + ctrl->server_local->containername = NULL; assuan_close_input_fd (ctx); assuan_close_output_fd (ctx); } -/* Helper to print a message while leaving a command. */ -static gpg_error_t -leave_cmd (assuan_context_t ctx, gpg_error_t err) -{ - if (err) - { - const char *name = assuan_get_command_name (ctx); - if (!name) - name = "?"; - if (gpg_err_source (err) == GPG_ERR_SOURCE_DEFAULT) - log_error ("command '%s' failed: %s\n", name, - gpg_strerror (err)); - else - log_error ("command '%s' failed: %s <%s>\n", name, - gpg_strerror (err), gpg_strsource (err)); - } - return err; -} - - -/* RECIPIENT <userID> +/* OPEN [options] <filename> - FIXME - description. - All RECIPIENT commands are cumulative until a RESET or an - successful CREATE command. + Open the container FILENAME. FILENAME must be percent-plus + escaped. A quick check to see whether this is a suitable G13 + container file is done. However no cryptographic check or any + other check is done. This command is used to define the target for + further commands. The filename is reset with the RESET command, + another OPEN or the CREATE command. */ static gpg_error_t -cmd_recipient (assuan_context_t ctx, char *line) +cmd_open (assuan_context_t ctx, char *line) { ctrl_t ctrl = assuan_get_pointer (ctx); - gpg_error_t err; - - (void)ctrl; - err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); - /* err = gpgsm_add_to_certlist (ctrl, line, 0, */ - /* &ctrl->server_local->recplist, 0); */ - /* if (err) */ - /* { */ - /* gpgsm_status2 (ctrl, STATUS_INV_RECP, */ - /* get_inv_recpsgnr_code (rc), line, NULL); */ - /* } */ - - return leave_cmd (ctx, err); -} + gpg_error_t err = 0; + char *p, *pend; + size_t len; + /* In any case reset the active container. */ + xfree (ctrl->server_local->containername); + ctrl->server_local->containername = NULL; -/* SIGNER <userID> + /* Parse the line. */ + line = skip_options (line); + for (p=line; *p && !spacep (p); p++) + ; + pend = p; + while (spacep(p)) + p++; + if (*p || pend == line) + { + err = gpg_error (GPG_ERR_ASS_SYNTAX); + goto leave; + } + *pend = 0; - FIXME - description. - */ -static gpg_error_t -cmd_signer (assuan_context_t ctx, char *line) -{ - ctrl_t ctrl = assuan_get_pointer (ctx); - gpg_error_t err; + /* Unescape the line and check for embedded Nul bytes. */ + len = percent_plus_unescape_inplace (line, 0); + line[len] = 0; + if (!len || memchr (line, 0, len)) + { + err = gpg_error (GPG_ERR_INV_NAME); + goto leave; + } - (void)ctrl; + /* Do a basic check. */ + err = g13_is_container (ctrl, line); + if (err) + goto leave; - err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); + /* Store the filename. */ + ctrl->server_local->containername = xtrystrdup (line); + if (!ctrl->server_local->containername) + err = gpg_error_from_syserror (); + + + leave: return leave_cmd (ctx, err); } -/* SETMOUNTPOINT [options] [<dirname>] +/* MOUNT [options] [<mountpoint>] - Set DIRNAME as the new mount point for future operations. + Mount the currently open file onto MOUNTPOINT. If MOUNTPOINT is + not given the system picks an unused mountpoint. MOUNTPOINT must + be percent-plus escaped to allow for arbitrary names. */ static gpg_error_t -cmd_setmountpoint (assuan_context_t ctx, char *line) +cmd_mount (assuan_context_t ctx, char *line) { ctrl_t ctrl = assuan_get_pointer (ctx); gpg_error_t err = 0; @@ -319,40 +295,28 @@ cmd_setmountpoint (assuan_context_t ctx, char *line) goto leave; } - xfree (ctrl->server_local->mountpoint); - if (!len) /* Reset mountpoint. */ - ctrl->server_local->mountpoint = NULL; - else + if (!ctrl->server_local->containername) { - ctrl->server_local->mountpoint = xtrystrdup (line); - if (!ctrl->server_local->mountpoint) - err = gpg_error_from_syserror (); + err = gpg_error (GPG_ERR_MISSING_ACTION); + goto leave; } - if (!err) - log_debug ("mountpoint is now `%s'\n", - ctrl->server_local->mountpoint - ? ctrl->server_local->mountpoint: "[none]"); + /* Perform the mount. */ + err = g13_mount_container (ctrl, ctrl->server_local->containername, + *line? line : NULL); leave: return leave_cmd (ctx, err); } -/* MOUNT [options] <containername> +/* UMOUNT [options] [<mountpoint>] - Mount CONTAINERNAME onto the current mount point. CONTAINERNAME is - the name of a file in the g13 format and must be percent-plus - escaped to allow for arbitrary names. The mount poiunt must have - been set already. - - - A reason why we use a separate command for the mount point is to - allow for longer filenames (an assuan command line is limited to - ~1000 byte. + Unmount the currently open file or the one opened at MOUNTPOINT. + MOUNTPOINT must be percent-plus escaped. */ static gpg_error_t -cmd_mount (assuan_context_t ctx, char *line) +cmd_umount (assuan_context_t ctx, char *line) { ctrl_t ctrl = assuan_get_pointer (ctx); gpg_error_t err = 0; @@ -365,7 +329,7 @@ cmd_mount (assuan_context_t ctx, char *line) pend = p; while (spacep(p)) p++; - if (*p || pend == line) + if (*p) { err = gpg_error (GPG_ERR_ASS_SYNTAX); goto leave; @@ -375,20 +339,89 @@ cmd_mount (assuan_context_t ctx, char *line) /* Unescape the line and check for embedded Nul bytes. */ len = percent_plus_unescape_inplace (line, 0); line[len] = 0; - if (!len || memchr (line, 0, len)) + if (memchr (line, 0, len)) { err = gpg_error (GPG_ERR_INV_NAME); goto leave; } - - /* Perform the mount. */ - err = g13_mount_container (ctrl, line, ctrl->server_local->mountpoint); + + /* Perform the unmount. */ + err = g13_umount_container (ctrl, ctrl->server_local->containername, + *line? line : NULL); leave: return leave_cmd (ctx, err); } + +/* RECIPIENT <userID> + + FIXME - description. + All RECIPIENT commands are cumulative until a RESET or an + successful CREATE command. + */ +static gpg_error_t +cmd_recipient (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + gpg_error_t err; + + (void)ctrl; + err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); + /* err = gpgsm_add_to_certlist (ctrl, line, 0, */ + /* &ctrl->server_local->recplist, 0); */ + /* if (err) */ + /* { */ + /* gpgsm_status2 (ctrl, STATUS_INV_RECP, */ + /* get_inv_recpsgnr_code (rc), line, NULL); */ + /* } */ + + return leave_cmd (ctx, err); +} + + +/* SIGNER <userID> + + FIXME - description. + */ +static gpg_error_t +cmd_signer (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + gpg_error_t err; + + (void)ctrl; + + err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); + return leave_cmd (ctx, err); +} + + +/* CREATE [options] filename + + Create a new container. On success the OPEN command is done + implictly for the new container. + */ +static gpg_error_t +cmd_create (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + gpg_error_t err; + + (void)ctrl; + + /* First we close the active container. */ + xfree (ctrl->server_local->containername); + ctrl->server_local->containername = NULL; + + + + err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); + return leave_cmd (ctx, err); +} + + /* GETINFO <what> Multipurpose function to return a variety of information. @@ -476,10 +509,12 @@ register_commands (assuan_context_t ctx) const char *name; gpg_error_t (*handler)(assuan_context_t, char *line); } table[] = { + { "OPEN", cmd_open }, + { "MOUNT", cmd_mount }, + { "UMOUNT", cmd_umount }, { "RECIPIENT", cmd_recipient }, { "SIGNER", cmd_signer }, - { "MOUNT", cmd_mount }, - { "SETMOUNTPOINT", cmd_setmountpoint }, + { "CREATE", cmd_create }, { "INPUT", NULL }, { "OUTPUT", NULL }, { "GETINFO", cmd_getinfo }, |