diff options
author | Мирослав Николић <[email protected]> | 2014-11-27 19:41:37 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2014-11-27 19:41:37 +0000 |
commit | f173cdcdfbfd083b035516a406c2c754f38a0ace (patch) | |
tree | b1f162fcb7e39ade104379129f6731aacdce2344 /agent/command.c | |
parent | agent: Make auditing of the option list easier. (diff) | |
download | gnupg-f173cdcdfbfd083b035516a406c2c754f38a0ace.tar.gz gnupg-f173cdcdfbfd083b035516a406c2c754f38a0ace.zip |
gpg-agent: Add restricted connection feature.
* agent/agent.h (opt): Add field extra_socket.
(server_control_s): Add field restricted.
* agent/command.c: Check restricted flag on many commands.
* agent/gpg-agent.c (oExtraSocket): New.
(opts): Add option --extra-socket.
(socket_name_extra): New.
(cleanup): Cleanup that socket name.
(main): Implement oExtraSocket.
(create_socket_name): Add arg homedir and change all callers.
(create_server_socket): Rename arg is_ssh to primary and change
callers.
(start_connection_thread): Take ctrl as arg.
(start_connection_thread_std): New.
(start_connection_thread_extra): New.
(handle_connections): Add arg listen_fd_extra and replace the
connection starting code by parameterized loop.
* common/asshelp.c (start_new_gpg_agent): Detect the use of the
restricted mode and don't fail on sending the pinentry environment.
* common/util.h (GPG_ERR_FORBIDDEN): New.
Diffstat (limited to 'agent/command.c')
-rw-r--r-- | agent/command.c | 180 |
1 files changed, 138 insertions, 42 deletions
diff --git a/agent/command.c b/agent/command.c index 11bfbeb67..3e8066381 100644 --- a/agent/command.c +++ b/agent/command.c @@ -502,6 +502,9 @@ cmd_geteventcounter (assuan_context_t ctx, char *line) (void)line; + if (ctrl->restricted) + return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN)); + return agent_print_status (ctrl, "EVENTCOUNTER", "%u %u %u", eventcounter.any, eventcounter.key, @@ -577,10 +580,14 @@ static const char hlp_listtrusted[] = static gpg_error_t cmd_listtrusted (assuan_context_t ctx, char *line) { + ctrl_t ctrl = assuan_get_pointer (ctx); int rc; (void)line; + if (ctrl->restricted) + return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN)); + rc = agent_listtrusted (ctx); return leave_cmd (ctx, rc); } @@ -599,6 +606,9 @@ cmd_marktrusted (assuan_context_t ctx, char *line) char fpr[41]; int flag; + if (ctrl->restricted) + return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN)); + /* parse the fingerprint value */ for (p=line,n=0; hexdigitp (p); p++, n++) ; @@ -718,7 +728,12 @@ cmd_setkeydesc (assuan_context_t ctx, char *line) plus_to_blank (desc); xfree (ctrl->server_local->keydesc); - ctrl->server_local->keydesc = xtrystrdup (desc); + + if (ctrl->restricted) + ctrl->server_local->keydesc = strconcat + ("Note: Request from a remote site.\n\n", desc, NULL); + else + ctrl->server_local->keydesc = xtrystrdup (desc); if (!ctrl->server_local->keydesc) return out_of_core (); return 0; @@ -928,6 +943,9 @@ cmd_genkey (assuan_context_t ctx, char *line) int opt_preset; char *p; + if (ctrl->restricted) + return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN)); + opt_preset = has_option (line, "--preset"); no_protection = has_option (line, "--no-protection"); line = skip_options (line); @@ -974,6 +992,9 @@ cmd_readkey (assuan_context_t ctx, char *line) unsigned char grip[20]; gcry_sexp_t s_pkey = NULL; + if (ctrl->restricted) + return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN)); + rc = parse_keygrip (ctx, line, grip); if (rc) return rc; /* Return immediately as this is already an Assuan error code.*/ @@ -1199,6 +1220,9 @@ cmd_keyinfo (assuan_context_t ctx, char *line) char hexgrip[41]; int disabled, ttl, confirm, is_ssh; + if (ctrl->restricted) + return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN)); + if (has_option (line, "--ssh-list")) list_mode = 2; else @@ -1376,6 +1400,9 @@ cmd_get_passphrase (assuan_context_t ctx, char *line) int opt_repeat = 0; char *repeat_errtext = NULL; + if (ctrl->restricted) + return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN)); + opt_data = has_option (line, "--data"); opt_check = has_option (line, "--check"); opt_no_ask = has_option (line, "--no-ask"); @@ -1515,10 +1542,14 @@ static const char hlp_clear_passphrase[] = static gpg_error_t cmd_clear_passphrase (assuan_context_t ctx, char *line) { + ctrl_t ctrl = assuan_get_pointer (ctx); char *cacheid = NULL; char *p; int opt_normal; + if (ctrl->restricted) + return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN)); + opt_normal = has_option (line, "--mode=normal"); line = skip_options (line); @@ -1557,6 +1588,9 @@ cmd_get_confirmation (assuan_context_t ctx, char *line) char *desc = NULL; char *p; + if (ctrl->restricted) + return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN)); + /* parse the stuff */ for (p=line; *p == ' '; p++) ; @@ -1595,6 +1629,9 @@ cmd_learn (assuan_context_t ctx, char *line) ctrl_t ctrl = assuan_get_pointer (ctx); int rc; + if (ctrl->restricted) + return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN)); + rc = agent_handle_learn (ctrl, has_option (line, "--send")? ctx : NULL); return leave_cmd (ctx, rc); } @@ -1621,6 +1658,9 @@ cmd_passwd (assuan_context_t ctx, char *line) char *pend; int opt_preset; + if (ctrl->restricted) + return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN)); + opt_preset = has_option (line, "--preset"); cache_nonce = option_value (line, "--cache-nonce"); if (cache_nonce) @@ -1756,6 +1796,7 @@ static const char hlp_preset_passphrase[] = static gpg_error_t cmd_preset_passphrase (assuan_context_t ctx, char *line) { + ctrl_t ctrl = assuan_get_pointer (ctx); int rc; char *grip_clear = NULL; unsigned char *passphrase = NULL; @@ -1763,6 +1804,9 @@ cmd_preset_passphrase (assuan_context_t ctx, char *line) size_t len; int opt_inquire; + if (ctrl->restricted) + return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN)); + if (!opt.allow_preset_passphrase) return set_error (GPG_ERR_NOT_SUPPORTED, "no --allow-preset-passphrase"); @@ -1847,6 +1891,9 @@ cmd_scd (assuan_context_t ctx, char *line) ctrl_t ctrl = assuan_get_pointer (ctx); int rc; + if (ctrl->restricted) + return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN)); + rc = divert_generic_cmd (ctrl, line, ctx); return rc; @@ -1876,6 +1923,8 @@ cmd_keywrap_key (assuan_context_t ctx, char *line) gpg_error_t err = 0; int clearopt = has_option (line, "--clear"); + if (ctrl->restricted) + return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN)); assuan_begin_confidential (ctx); if (has_option (line, "--import")) @@ -1940,6 +1989,9 @@ cmd_import_key (assuan_context_t ctx, char *line) char *cache_nonce = NULL; char *p; + if (ctrl->restricted) + return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN)); + if (!ctrl->server_local->import_key) { err = gpg_error (GPG_ERR_MISSING_KEY); @@ -2129,6 +2181,9 @@ cmd_export_key (assuan_context_t ctx, char *line) char *pend; int c; + if (ctrl->restricted) + return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN)); + openpgp = has_option (line, "--openpgp"); cache_nonce = option_value (line, "--cache-nonce"); if (cache_nonce) @@ -2280,6 +2335,9 @@ cmd_delete_key (assuan_context_t ctx, char *line) gpg_error_t err; unsigned char grip[20]; + if (ctrl->restricted) + return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN)); + line = skip_options (line); err = parse_keygrip (ctx, line, grip); @@ -2318,6 +2376,9 @@ cmd_keytocard (assuan_context_t ctx, char *line) unsigned char *shdkey; time_t timestamp; + if (ctrl->restricted) + return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN)); + force = has_option (line, "--force"); line = skip_options (line); @@ -2434,6 +2495,8 @@ cmd_keytocard (assuan_context_t ctx, char *line) leave: return leave_cmd (ctx, err); } + + static const char hlp_getval[] = "GETVAL <key>\n" @@ -2443,11 +2506,15 @@ static const char hlp_getval[] = static gpg_error_t cmd_getval (assuan_context_t ctx, char *line) { + ctrl_t ctrl = assuan_get_pointer (ctx); int rc = 0; char *key = NULL; char *p; struct putval_item_s *vl; + if (ctrl->restricted) + return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN)); + for (p=line; *p == ' '; p++) ; key = p; @@ -2498,6 +2565,7 @@ static const char hlp_putval[] = static gpg_error_t cmd_putval (assuan_context_t ctx, char *line) { + ctrl_t ctrl = assuan_get_pointer (ctx); int rc = 0; char *key = NULL; char *value = NULL; @@ -2505,6 +2573,9 @@ cmd_putval (assuan_context_t ctx, char *line) char *p; struct putval_item_s *vl, *vlprev; + if (ctrl->restricted) + return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN)); + for (p=line; *p == ' '; p++) ; key = p; @@ -2583,6 +2654,9 @@ cmd_updatestartuptty (assuan_context_t ctx, char *line) (void)line; + if (ctrl->restricted) + return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN)); + se = session_env_new (); if (!se) err = gpg_error_from_syserror (); @@ -2634,6 +2708,9 @@ cmd_killagent (assuan_context_t ctx, char *line) (void)line; + if (ctrl->restricted) + return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN)); + ctrl->server_local->stopme = 1; assuan_set_flag (ctx, ASSUAN_FORCE_CLOSE, 1); return 0; @@ -2648,9 +2725,13 @@ static const char hlp_reloadagent[] = static gpg_error_t cmd_reloadagent (assuan_context_t ctx, char *line) { - (void)ctx; + ctrl_t ctrl = assuan_get_pointer (ctx); + (void)line; + if (ctrl->restricted) + return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN)); + agent_sighup_action (); return 0; } @@ -2672,7 +2753,8 @@ static const char hlp_getinfo[] = " std_session_env - List the standard session environment.\n" " std_startup_env - List the standard startup environment.\n" " cmd_has_option\n" - " - Returns OK if the command CMD implements the option OPT\n."; + " - Returns OK if the command CMD implements the option OPT.\n" + " restricted - Returns OK if the connection is in restricted mode.\n"; static gpg_error_t cmd_getinfo (assuan_context_t ctx, char *line) { @@ -2684,6 +2766,54 @@ cmd_getinfo (assuan_context_t ctx, char *line) const char *s = VERSION; rc = assuan_send_data (ctx, s, strlen (s)); } + else if (!strncmp (line, "cmd_has_option", 14) + && (line[14] == ' ' || line[14] == '\t' || !line[14])) + { + char *cmd, *cmdopt; + line += 14; + while (*line == ' ' || *line == '\t') + line++; + if (!*line) + rc = gpg_error (GPG_ERR_MISSING_VALUE); + else + { + cmd = line; + while (*line && (*line != ' ' && *line != '\t')) + line++; + if (!*line) + rc = gpg_error (GPG_ERR_MISSING_VALUE); + else + { + *line++ = 0; + while (*line == ' ' || *line == '\t') + line++; + if (!*line) + rc = gpg_error (GPG_ERR_MISSING_VALUE); + else + { + cmdopt = line; + if (!command_has_option (cmd, cmdopt)) + rc = gpg_error (GPG_ERR_GENERAL); + } + } + } + } + else if (!strcmp (line, "s2k_count")) + { + char numbuf[50]; + + snprintf (numbuf, sizeof numbuf, "%lu", get_standard_s2k_count ()); + rc = assuan_send_data (ctx, numbuf, strlen (numbuf)); + } + else if (!strcmp (line, "restricted")) + { + rc = ctrl->restricted? 0 : gpg_error (GPG_ERR_GENERAL); + } + else if (ctrl->restricted) + { + rc = gpg_error (GPG_ERR_FORBIDDEN); + } + /* All sub-commands below are not allowed in restricted mode. */ else if (!strcmp (line, "pid")) { char numbuf[50]; @@ -2713,13 +2843,6 @@ cmd_getinfo (assuan_context_t ctx, char *line) { rc = agent_scd_check_running ()? 0 : gpg_error (GPG_ERR_GENERAL); } - else if (!strcmp (line, "s2k_count")) - { - char numbuf[50]; - - snprintf (numbuf, sizeof numbuf, "%lu", get_standard_s2k_count ()); - rc = assuan_send_data (ctx, numbuf, strlen (numbuf)); - } else if (!strcmp (line, "std_session_env") || !strcmp (line, "std_startup_env")) { @@ -2748,38 +2871,6 @@ cmd_getinfo (assuan_context_t ctx, char *line) } } } - else if (!strncmp (line, "cmd_has_option", 14) - && (line[14] == ' ' || line[14] == '\t' || !line[14])) - { - char *cmd, *cmdopt; - line += 14; - while (*line == ' ' || *line == '\t') - line++; - if (!*line) - rc = gpg_error (GPG_ERR_MISSING_VALUE); - else - { - cmd = line; - while (*line && (*line != ' ' && *line != '\t')) - line++; - if (!*line) - rc = gpg_error (GPG_ERR_MISSING_VALUE); - else - { - *line++ = 0; - while (*line == ' ' || *line == '\t') - line++; - if (!*line) - rc = gpg_error (GPG_ERR_MISSING_VALUE); - else - { - cmdopt = line; - if (!command_has_option (cmd, cmdopt)) - rc = gpg_error (GPG_ERR_GENERAL); - } - } - } - } else rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT"); return rc; @@ -2802,6 +2893,11 @@ option_handler (assuan_context_t ctx, const char *key, const char *value) ctrl->server_local->allow_fully_canceled = gnupg_compare_version (value, "2.1.0"); } + else if (ctrl->restricted) + { + err = gpg_error (GPG_ERR_FORBIDDEN); + } + /* All options below are not allowed in restricted mode. */ else if (!strcmp (key, "putenv")) { /* Change the session's environment to be used for the |