diff --git a/agent/command.c b/agent/command.c index f9bc6ca96..8bb9b6a70 100644 --- a/agent/command.c +++ b/agent/command.c @@ -3101,6 +3101,21 @@ option_handler (assuan_context_t ctx, const char *key, const char *value) ctrl->s2k_count = 0; } } + else if (!strcmp (key, "pretend-request-origin")) + { + log_assert (!ctrl->restricted); + switch (parse_request_origin (value)) + { + case REQUEST_ORIGIN_LOCAL: ctrl->restricted = 0; break; + case REQUEST_ORIGIN_REMOTE: ctrl->restricted = 1; break; + case REQUEST_ORIGIN_BROWSER: ctrl->restricted = 2; break; + default: + err = gpg_error (GPG_ERR_INV_VALUE); + /* Better pretend to be remote in case of a bad value. */ + ctrl->restricted = 1; + break; + } + } else err = gpg_error (GPG_ERR_UNKNOWN_OPTION); diff --git a/common/agent-opt.c b/common/agent-opt.c index b32448242..6d9f9e77e 100644 --- a/common/agent-opt.c +++ b/common/agent-opt.c @@ -69,3 +69,38 @@ str_pinentry_mode (pinentry_mode_t mode) } return "?"; } + + +/* Parse VALUE and return an integer representing a request_origin_t. + * (-1) is returned for an invalid VALUE. */ +int +parse_request_origin (const char *value) +{ + int result; + + if (!strcmp (value, "none") || !strcmp (value, "local")) + result = REQUEST_ORIGIN_LOCAL; + else if (!strcmp (value, "remote")) + result = REQUEST_ORIGIN_REMOTE; + else if (!strcmp (value, "browser")) + result = REQUEST_ORIGIN_BROWSER; + else + result = -1; + + return result; +} + + +/* Return the string representation for the request origin. Returns + * "?" for an invalid mode. */ +const char * +str_request_origin (request_origin_t mode) +{ + switch (mode) + { + case REQUEST_ORIGIN_LOCAL: return "local"; + case REQUEST_ORIGIN_REMOTE: return "remote"; + case REQUEST_ORIGIN_BROWSER: return "browser"; + } + return "?"; +} diff --git a/common/shareddefs.h b/common/shareddefs.h index 1594f6650..4b1442133 100644 --- a/common/shareddefs.h +++ b/common/shareddefs.h @@ -39,10 +39,23 @@ typedef enum pinentry_mode_t; +/* Values for the request origin. */ +typedef enum + { + REQUEST_ORIGIN_LOCAL = 0, + REQUEST_ORIGIN_REMOTE, + REQUEST_ORIGIN_BROWSER + } +request_origin_t; + + /*-- agent-opt.c --*/ int parse_pinentry_mode (const char *value); const char *str_pinentry_mode (pinentry_mode_t mode); +int parse_request_origin (const char *value); +const char *str_request_origin (request_origin_t mode); + #endif /*GNUPG_COMMON_SHAREDDEFS_H*/ diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi index 4781bbdca..bcce03329 100644 --- a/doc/gpg-agent.texi +++ b/doc/gpg-agent.texi @@ -1581,6 +1581,27 @@ option is valid for the entire session or until reset to 0. This option is useful if the key is later used on boxes which are either much slower or faster than the actual box. +@item pretend-request-origin +This option switches the connection into a restricted mode which +handles all further commands in the same way as they would be handled +when originating from the extra or browser socket. Note that this +option is not available in the restricted mode. Valid values for this +option are: + + @table @code + @item none + @itemx local + This is a NOP and leaves the connection in the standard way. + + @item remote + Pretend to come from a remote origin in the same way as connections + from the @option{--extra-socket}. + + @item browser + Pretend to come from a local web browser in the same way as connections + from the @option{--browser-socket}. + @end table + @end table