mirror of
git://git.gnupg.org/gnupg.git
synced 2025-04-13 22:21:09 +02:00
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.
This commit is contained in:
parent
ccee34736b
commit
f173cdcdfb
@ -130,6 +130,11 @@ struct
|
|||||||
|
|
||||||
/* This global option enables the ssh-agent subsystem. */
|
/* This global option enables the ssh-agent subsystem. */
|
||||||
int ssh_support;
|
int ssh_support;
|
||||||
|
|
||||||
|
/* This global options indicates the use of an extra socket. Note
|
||||||
|
that we use a hack for cleanup handling in gpg-agent.c: If the
|
||||||
|
value is less than 2 the name has not yet been malloced. */
|
||||||
|
int extra_socket;
|
||||||
} opt;
|
} opt;
|
||||||
|
|
||||||
|
|
||||||
@ -171,6 +176,9 @@ struct server_control_s
|
|||||||
gnupg_fd_t fd;
|
gnupg_fd_t fd;
|
||||||
} thread_startup;
|
} thread_startup;
|
||||||
|
|
||||||
|
/* Flag indicating the connection is run in restricted mode. */
|
||||||
|
int restricted;
|
||||||
|
|
||||||
/* Private data of the server (command.c). */
|
/* Private data of the server (command.c). */
|
||||||
struct server_local_s *server_local;
|
struct server_local_s *server_local;
|
||||||
|
|
||||||
|
230
agent/command.c
230
agent/command.c
@ -502,6 +502,9 @@ cmd_geteventcounter (assuan_context_t ctx, char *line)
|
|||||||
|
|
||||||
(void)line;
|
(void)line;
|
||||||
|
|
||||||
|
if (ctrl->restricted)
|
||||||
|
return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
|
||||||
|
|
||||||
return agent_print_status (ctrl, "EVENTCOUNTER", "%u %u %u",
|
return agent_print_status (ctrl, "EVENTCOUNTER", "%u %u %u",
|
||||||
eventcounter.any,
|
eventcounter.any,
|
||||||
eventcounter.key,
|
eventcounter.key,
|
||||||
@ -577,10 +580,14 @@ static const char hlp_listtrusted[] =
|
|||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
cmd_listtrusted (assuan_context_t ctx, char *line)
|
cmd_listtrusted (assuan_context_t ctx, char *line)
|
||||||
{
|
{
|
||||||
|
ctrl_t ctrl = assuan_get_pointer (ctx);
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
(void)line;
|
(void)line;
|
||||||
|
|
||||||
|
if (ctrl->restricted)
|
||||||
|
return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
|
||||||
|
|
||||||
rc = agent_listtrusted (ctx);
|
rc = agent_listtrusted (ctx);
|
||||||
return leave_cmd (ctx, rc);
|
return leave_cmd (ctx, rc);
|
||||||
}
|
}
|
||||||
@ -599,6 +606,9 @@ cmd_marktrusted (assuan_context_t ctx, char *line)
|
|||||||
char fpr[41];
|
char fpr[41];
|
||||||
int flag;
|
int flag;
|
||||||
|
|
||||||
|
if (ctrl->restricted)
|
||||||
|
return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
|
||||||
|
|
||||||
/* parse the fingerprint value */
|
/* parse the fingerprint value */
|
||||||
for (p=line,n=0; hexdigitp (p); p++, n++)
|
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);
|
plus_to_blank (desc);
|
||||||
|
|
||||||
xfree (ctrl->server_local->keydesc);
|
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)
|
if (!ctrl->server_local->keydesc)
|
||||||
return out_of_core ();
|
return out_of_core ();
|
||||||
return 0;
|
return 0;
|
||||||
@ -928,6 +943,9 @@ cmd_genkey (assuan_context_t ctx, char *line)
|
|||||||
int opt_preset;
|
int opt_preset;
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
|
if (ctrl->restricted)
|
||||||
|
return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
|
||||||
|
|
||||||
opt_preset = has_option (line, "--preset");
|
opt_preset = has_option (line, "--preset");
|
||||||
no_protection = has_option (line, "--no-protection");
|
no_protection = has_option (line, "--no-protection");
|
||||||
line = skip_options (line);
|
line = skip_options (line);
|
||||||
@ -974,6 +992,9 @@ cmd_readkey (assuan_context_t ctx, char *line)
|
|||||||
unsigned char grip[20];
|
unsigned char grip[20];
|
||||||
gcry_sexp_t s_pkey = NULL;
|
gcry_sexp_t s_pkey = NULL;
|
||||||
|
|
||||||
|
if (ctrl->restricted)
|
||||||
|
return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
|
||||||
|
|
||||||
rc = parse_keygrip (ctx, line, grip);
|
rc = parse_keygrip (ctx, line, grip);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc; /* Return immediately as this is already an Assuan error code.*/
|
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];
|
char hexgrip[41];
|
||||||
int disabled, ttl, confirm, is_ssh;
|
int disabled, ttl, confirm, is_ssh;
|
||||||
|
|
||||||
|
if (ctrl->restricted)
|
||||||
|
return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
|
||||||
|
|
||||||
if (has_option (line, "--ssh-list"))
|
if (has_option (line, "--ssh-list"))
|
||||||
list_mode = 2;
|
list_mode = 2;
|
||||||
else
|
else
|
||||||
@ -1376,6 +1400,9 @@ cmd_get_passphrase (assuan_context_t ctx, char *line)
|
|||||||
int opt_repeat = 0;
|
int opt_repeat = 0;
|
||||||
char *repeat_errtext = NULL;
|
char *repeat_errtext = NULL;
|
||||||
|
|
||||||
|
if (ctrl->restricted)
|
||||||
|
return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
|
||||||
|
|
||||||
opt_data = has_option (line, "--data");
|
opt_data = has_option (line, "--data");
|
||||||
opt_check = has_option (line, "--check");
|
opt_check = has_option (line, "--check");
|
||||||
opt_no_ask = has_option (line, "--no-ask");
|
opt_no_ask = has_option (line, "--no-ask");
|
||||||
@ -1515,10 +1542,14 @@ static const char hlp_clear_passphrase[] =
|
|||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
cmd_clear_passphrase (assuan_context_t ctx, char *line)
|
cmd_clear_passphrase (assuan_context_t ctx, char *line)
|
||||||
{
|
{
|
||||||
|
ctrl_t ctrl = assuan_get_pointer (ctx);
|
||||||
char *cacheid = NULL;
|
char *cacheid = NULL;
|
||||||
char *p;
|
char *p;
|
||||||
int opt_normal;
|
int opt_normal;
|
||||||
|
|
||||||
|
if (ctrl->restricted)
|
||||||
|
return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
|
||||||
|
|
||||||
opt_normal = has_option (line, "--mode=normal");
|
opt_normal = has_option (line, "--mode=normal");
|
||||||
line = skip_options (line);
|
line = skip_options (line);
|
||||||
|
|
||||||
@ -1557,6 +1588,9 @@ cmd_get_confirmation (assuan_context_t ctx, char *line)
|
|||||||
char *desc = NULL;
|
char *desc = NULL;
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
|
if (ctrl->restricted)
|
||||||
|
return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
|
||||||
|
|
||||||
/* parse the stuff */
|
/* parse the stuff */
|
||||||
for (p=line; *p == ' '; p++)
|
for (p=line; *p == ' '; p++)
|
||||||
;
|
;
|
||||||
@ -1595,6 +1629,9 @@ cmd_learn (assuan_context_t ctx, char *line)
|
|||||||
ctrl_t ctrl = assuan_get_pointer (ctx);
|
ctrl_t ctrl = assuan_get_pointer (ctx);
|
||||||
int rc;
|
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);
|
rc = agent_handle_learn (ctrl, has_option (line, "--send")? ctx : NULL);
|
||||||
return leave_cmd (ctx, rc);
|
return leave_cmd (ctx, rc);
|
||||||
}
|
}
|
||||||
@ -1621,6 +1658,9 @@ cmd_passwd (assuan_context_t ctx, char *line)
|
|||||||
char *pend;
|
char *pend;
|
||||||
int opt_preset;
|
int opt_preset;
|
||||||
|
|
||||||
|
if (ctrl->restricted)
|
||||||
|
return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
|
||||||
|
|
||||||
opt_preset = has_option (line, "--preset");
|
opt_preset = has_option (line, "--preset");
|
||||||
cache_nonce = option_value (line, "--cache-nonce");
|
cache_nonce = option_value (line, "--cache-nonce");
|
||||||
if (cache_nonce)
|
if (cache_nonce)
|
||||||
@ -1756,6 +1796,7 @@ static const char hlp_preset_passphrase[] =
|
|||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
cmd_preset_passphrase (assuan_context_t ctx, char *line)
|
cmd_preset_passphrase (assuan_context_t ctx, char *line)
|
||||||
{
|
{
|
||||||
|
ctrl_t ctrl = assuan_get_pointer (ctx);
|
||||||
int rc;
|
int rc;
|
||||||
char *grip_clear = NULL;
|
char *grip_clear = NULL;
|
||||||
unsigned char *passphrase = NULL;
|
unsigned char *passphrase = NULL;
|
||||||
@ -1763,6 +1804,9 @@ cmd_preset_passphrase (assuan_context_t ctx, char *line)
|
|||||||
size_t len;
|
size_t len;
|
||||||
int opt_inquire;
|
int opt_inquire;
|
||||||
|
|
||||||
|
if (ctrl->restricted)
|
||||||
|
return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
|
||||||
|
|
||||||
if (!opt.allow_preset_passphrase)
|
if (!opt.allow_preset_passphrase)
|
||||||
return set_error (GPG_ERR_NOT_SUPPORTED, "no --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);
|
ctrl_t ctrl = assuan_get_pointer (ctx);
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
if (ctrl->restricted)
|
||||||
|
return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
|
||||||
|
|
||||||
rc = divert_generic_cmd (ctrl, line, ctx);
|
rc = divert_generic_cmd (ctrl, line, ctx);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
@ -1876,6 +1923,8 @@ cmd_keywrap_key (assuan_context_t ctx, char *line)
|
|||||||
gpg_error_t err = 0;
|
gpg_error_t err = 0;
|
||||||
int clearopt = has_option (line, "--clear");
|
int clearopt = has_option (line, "--clear");
|
||||||
|
|
||||||
|
if (ctrl->restricted)
|
||||||
|
return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
|
||||||
|
|
||||||
assuan_begin_confidential (ctx);
|
assuan_begin_confidential (ctx);
|
||||||
if (has_option (line, "--import"))
|
if (has_option (line, "--import"))
|
||||||
@ -1940,6 +1989,9 @@ cmd_import_key (assuan_context_t ctx, char *line)
|
|||||||
char *cache_nonce = NULL;
|
char *cache_nonce = NULL;
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
|
if (ctrl->restricted)
|
||||||
|
return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
|
||||||
|
|
||||||
if (!ctrl->server_local->import_key)
|
if (!ctrl->server_local->import_key)
|
||||||
{
|
{
|
||||||
err = gpg_error (GPG_ERR_MISSING_KEY);
|
err = gpg_error (GPG_ERR_MISSING_KEY);
|
||||||
@ -2129,6 +2181,9 @@ cmd_export_key (assuan_context_t ctx, char *line)
|
|||||||
char *pend;
|
char *pend;
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
|
if (ctrl->restricted)
|
||||||
|
return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
|
||||||
|
|
||||||
openpgp = has_option (line, "--openpgp");
|
openpgp = has_option (line, "--openpgp");
|
||||||
cache_nonce = option_value (line, "--cache-nonce");
|
cache_nonce = option_value (line, "--cache-nonce");
|
||||||
if (cache_nonce)
|
if (cache_nonce)
|
||||||
@ -2280,6 +2335,9 @@ cmd_delete_key (assuan_context_t ctx, char *line)
|
|||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
unsigned char grip[20];
|
unsigned char grip[20];
|
||||||
|
|
||||||
|
if (ctrl->restricted)
|
||||||
|
return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
|
||||||
|
|
||||||
line = skip_options (line);
|
line = skip_options (line);
|
||||||
|
|
||||||
err = parse_keygrip (ctx, line, grip);
|
err = parse_keygrip (ctx, line, grip);
|
||||||
@ -2318,6 +2376,9 @@ cmd_keytocard (assuan_context_t ctx, char *line)
|
|||||||
unsigned char *shdkey;
|
unsigned char *shdkey;
|
||||||
time_t timestamp;
|
time_t timestamp;
|
||||||
|
|
||||||
|
if (ctrl->restricted)
|
||||||
|
return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
|
||||||
|
|
||||||
force = has_option (line, "--force");
|
force = has_option (line, "--force");
|
||||||
line = skip_options (line);
|
line = skip_options (line);
|
||||||
|
|
||||||
@ -2434,6 +2495,8 @@ cmd_keytocard (assuan_context_t ctx, char *line)
|
|||||||
leave:
|
leave:
|
||||||
return leave_cmd (ctx, err);
|
return leave_cmd (ctx, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static const char hlp_getval[] =
|
static const char hlp_getval[] =
|
||||||
"GETVAL <key>\n"
|
"GETVAL <key>\n"
|
||||||
@ -2443,11 +2506,15 @@ static const char hlp_getval[] =
|
|||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
cmd_getval (assuan_context_t ctx, char *line)
|
cmd_getval (assuan_context_t ctx, char *line)
|
||||||
{
|
{
|
||||||
|
ctrl_t ctrl = assuan_get_pointer (ctx);
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
char *key = NULL;
|
char *key = NULL;
|
||||||
char *p;
|
char *p;
|
||||||
struct putval_item_s *vl;
|
struct putval_item_s *vl;
|
||||||
|
|
||||||
|
if (ctrl->restricted)
|
||||||
|
return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
|
||||||
|
|
||||||
for (p=line; *p == ' '; p++)
|
for (p=line; *p == ' '; p++)
|
||||||
;
|
;
|
||||||
key = p;
|
key = p;
|
||||||
@ -2498,6 +2565,7 @@ static const char hlp_putval[] =
|
|||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
cmd_putval (assuan_context_t ctx, char *line)
|
cmd_putval (assuan_context_t ctx, char *line)
|
||||||
{
|
{
|
||||||
|
ctrl_t ctrl = assuan_get_pointer (ctx);
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
char *key = NULL;
|
char *key = NULL;
|
||||||
char *value = NULL;
|
char *value = NULL;
|
||||||
@ -2505,6 +2573,9 @@ cmd_putval (assuan_context_t ctx, char *line)
|
|||||||
char *p;
|
char *p;
|
||||||
struct putval_item_s *vl, *vlprev;
|
struct putval_item_s *vl, *vlprev;
|
||||||
|
|
||||||
|
if (ctrl->restricted)
|
||||||
|
return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
|
||||||
|
|
||||||
for (p=line; *p == ' '; p++)
|
for (p=line; *p == ' '; p++)
|
||||||
;
|
;
|
||||||
key = p;
|
key = p;
|
||||||
@ -2583,6 +2654,9 @@ cmd_updatestartuptty (assuan_context_t ctx, char *line)
|
|||||||
|
|
||||||
(void)line;
|
(void)line;
|
||||||
|
|
||||||
|
if (ctrl->restricted)
|
||||||
|
return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
|
||||||
|
|
||||||
se = session_env_new ();
|
se = session_env_new ();
|
||||||
if (!se)
|
if (!se)
|
||||||
err = gpg_error_from_syserror ();
|
err = gpg_error_from_syserror ();
|
||||||
@ -2634,6 +2708,9 @@ cmd_killagent (assuan_context_t ctx, char *line)
|
|||||||
|
|
||||||
(void)line;
|
(void)line;
|
||||||
|
|
||||||
|
if (ctrl->restricted)
|
||||||
|
return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
|
||||||
|
|
||||||
ctrl->server_local->stopme = 1;
|
ctrl->server_local->stopme = 1;
|
||||||
assuan_set_flag (ctx, ASSUAN_FORCE_CLOSE, 1);
|
assuan_set_flag (ctx, ASSUAN_FORCE_CLOSE, 1);
|
||||||
return 0;
|
return 0;
|
||||||
@ -2648,9 +2725,13 @@ static const char hlp_reloadagent[] =
|
|||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
cmd_reloadagent (assuan_context_t ctx, char *line)
|
cmd_reloadagent (assuan_context_t ctx, char *line)
|
||||||
{
|
{
|
||||||
(void)ctx;
|
ctrl_t ctrl = assuan_get_pointer (ctx);
|
||||||
|
|
||||||
(void)line;
|
(void)line;
|
||||||
|
|
||||||
|
if (ctrl->restricted)
|
||||||
|
return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
|
||||||
|
|
||||||
agent_sighup_action ();
|
agent_sighup_action ();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -2672,7 +2753,8 @@ static const char hlp_getinfo[] =
|
|||||||
" std_session_env - List the standard session environment.\n"
|
" std_session_env - List the standard session environment.\n"
|
||||||
" std_startup_env - List the standard startup environment.\n"
|
" std_startup_env - List the standard startup environment.\n"
|
||||||
" cmd_has_option\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
|
static gpg_error_t
|
||||||
cmd_getinfo (assuan_context_t ctx, char *line)
|
cmd_getinfo (assuan_context_t ctx, char *line)
|
||||||
{
|
{
|
||||||
@ -2684,70 +2766,6 @@ cmd_getinfo (assuan_context_t ctx, char *line)
|
|||||||
const char *s = VERSION;
|
const char *s = VERSION;
|
||||||
rc = assuan_send_data (ctx, s, strlen (s));
|
rc = assuan_send_data (ctx, s, strlen (s));
|
||||||
}
|
}
|
||||||
else if (!strcmp (line, "pid"))
|
|
||||||
{
|
|
||||||
char numbuf[50];
|
|
||||||
|
|
||||||
snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
|
|
||||||
rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
|
|
||||||
}
|
|
||||||
else if (!strcmp (line, "socket_name"))
|
|
||||||
{
|
|
||||||
const char *s = get_agent_socket_name ();
|
|
||||||
|
|
||||||
if (s)
|
|
||||||
rc = assuan_send_data (ctx, s, strlen (s));
|
|
||||||
else
|
|
||||||
rc = gpg_error (GPG_ERR_NO_DATA);
|
|
||||||
}
|
|
||||||
else if (!strcmp (line, "ssh_socket_name"))
|
|
||||||
{
|
|
||||||
const char *s = get_agent_ssh_socket_name ();
|
|
||||||
|
|
||||||
if (s)
|
|
||||||
rc = assuan_send_data (ctx, s, strlen (s));
|
|
||||||
else
|
|
||||||
rc = gpg_error (GPG_ERR_NO_DATA);
|
|
||||||
}
|
|
||||||
else if (!strcmp (line, "scd_running"))
|
|
||||||
{
|
|
||||||
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"))
|
|
||||||
{
|
|
||||||
int iterator;
|
|
||||||
const char *name, *value;
|
|
||||||
char *string;
|
|
||||||
|
|
||||||
iterator = 0;
|
|
||||||
while ((name = session_env_list_stdenvnames (&iterator, NULL)))
|
|
||||||
{
|
|
||||||
value = session_env_getenv_or_default
|
|
||||||
(line[5] == 't'? opt.startup_env:ctrl->session_env, name, NULL);
|
|
||||||
if (value)
|
|
||||||
{
|
|
||||||
string = xtryasprintf ("%s=%s", name, value);
|
|
||||||
if (!string)
|
|
||||||
rc = gpg_error_from_syserror ();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rc = assuan_send_data (ctx, string, strlen (string)+1);
|
|
||||||
if (!rc)
|
|
||||||
rc = assuan_send_data (ctx, NULL, 0);
|
|
||||||
}
|
|
||||||
if (rc)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!strncmp (line, "cmd_has_option", 14)
|
else if (!strncmp (line, "cmd_has_option", 14)
|
||||||
&& (line[14] == ' ' || line[14] == '\t' || !line[14]))
|
&& (line[14] == ' ' || line[14] == '\t' || !line[14]))
|
||||||
{
|
{
|
||||||
@ -2780,6 +2798,79 @@ cmd_getinfo (assuan_context_t ctx, char *line)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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];
|
||||||
|
|
||||||
|
snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
|
||||||
|
rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
|
||||||
|
}
|
||||||
|
else if (!strcmp (line, "socket_name"))
|
||||||
|
{
|
||||||
|
const char *s = get_agent_socket_name ();
|
||||||
|
|
||||||
|
if (s)
|
||||||
|
rc = assuan_send_data (ctx, s, strlen (s));
|
||||||
|
else
|
||||||
|
rc = gpg_error (GPG_ERR_NO_DATA);
|
||||||
|
}
|
||||||
|
else if (!strcmp (line, "ssh_socket_name"))
|
||||||
|
{
|
||||||
|
const char *s = get_agent_ssh_socket_name ();
|
||||||
|
|
||||||
|
if (s)
|
||||||
|
rc = assuan_send_data (ctx, s, strlen (s));
|
||||||
|
else
|
||||||
|
rc = gpg_error (GPG_ERR_NO_DATA);
|
||||||
|
}
|
||||||
|
else if (!strcmp (line, "scd_running"))
|
||||||
|
{
|
||||||
|
rc = agent_scd_check_running ()? 0 : gpg_error (GPG_ERR_GENERAL);
|
||||||
|
}
|
||||||
|
else if (!strcmp (line, "std_session_env")
|
||||||
|
|| !strcmp (line, "std_startup_env"))
|
||||||
|
{
|
||||||
|
int iterator;
|
||||||
|
const char *name, *value;
|
||||||
|
char *string;
|
||||||
|
|
||||||
|
iterator = 0;
|
||||||
|
while ((name = session_env_list_stdenvnames (&iterator, NULL)))
|
||||||
|
{
|
||||||
|
value = session_env_getenv_or_default
|
||||||
|
(line[5] == 't'? opt.startup_env:ctrl->session_env, name, NULL);
|
||||||
|
if (value)
|
||||||
|
{
|
||||||
|
string = xtryasprintf ("%s=%s", name, value);
|
||||||
|
if (!string)
|
||||||
|
rc = gpg_error_from_syserror ();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rc = assuan_send_data (ctx, string, strlen (string)+1);
|
||||||
|
if (!rc)
|
||||||
|
rc = assuan_send_data (ctx, NULL, 0);
|
||||||
|
}
|
||||||
|
if (rc)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
|
rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT");
|
||||||
return rc;
|
return rc;
|
||||||
@ -2802,6 +2893,11 @@ option_handler (assuan_context_t ctx, const char *key, const char *value)
|
|||||||
ctrl->server_local->allow_fully_canceled =
|
ctrl->server_local->allow_fully_canceled =
|
||||||
gnupg_compare_version (value, "2.1.0");
|
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"))
|
else if (!strcmp (key, "putenv"))
|
||||||
{
|
{
|
||||||
/* Change the session's environment to be used for the
|
/* Change the session's environment to be used for the
|
||||||
|
@ -111,6 +111,7 @@ enum cmd_and_opt_values
|
|||||||
oEnablePassphraseHistory,
|
oEnablePassphraseHistory,
|
||||||
oUseStandardSocket,
|
oUseStandardSocket,
|
||||||
oNoUseStandardSocket,
|
oNoUseStandardSocket,
|
||||||
|
oExtraSocket,
|
||||||
oFakedSystemTime,
|
oFakedSystemTime,
|
||||||
|
|
||||||
oIgnoreCacheForSigning,
|
oIgnoreCacheForSigning,
|
||||||
@ -209,6 +210,7 @@ static ARGPARSE_OPTS opts[] = {
|
|||||||
/* */ "@"
|
/* */ "@"
|
||||||
#endif
|
#endif
|
||||||
),
|
),
|
||||||
|
ARGPARSE_s_s (oExtraSocket, "extra-socket", "@"),
|
||||||
|
|
||||||
/* Dummy options for backward compatibility. */
|
/* Dummy options for backward compatibility. */
|
||||||
ARGPARSE_o_s (oWriteEnvFile, "write-env-file", "@"),
|
ARGPARSE_o_s (oWriteEnvFile, "write-env-file", "@"),
|
||||||
@ -280,12 +282,16 @@ static int maybe_setuid = 1;
|
|||||||
/* Name of the communication socket used for native gpg-agent requests. */
|
/* Name of the communication socket used for native gpg-agent requests. */
|
||||||
static char *socket_name;
|
static char *socket_name;
|
||||||
|
|
||||||
|
/* Name of the optional extra socket used for native gpg-agent requests. */
|
||||||
|
static char *socket_name_extra;
|
||||||
|
|
||||||
/* Name of the communication socket used for ssh-agent-emulation. */
|
/* Name of the communication socket used for ssh-agent-emulation. */
|
||||||
static char *socket_name_ssh;
|
static char *socket_name_ssh;
|
||||||
|
|
||||||
/* We need to keep track of the server's nonces (these are dummies for
|
/* We need to keep track of the server's nonces (these are dummies for
|
||||||
POSIX systems). */
|
POSIX systems). */
|
||||||
static assuan_sock_nonce_t socket_nonce;
|
static assuan_sock_nonce_t socket_nonce;
|
||||||
|
static assuan_sock_nonce_t socket_nonce_extra;
|
||||||
static assuan_sock_nonce_t socket_nonce_ssh;
|
static assuan_sock_nonce_t socket_nonce_ssh;
|
||||||
|
|
||||||
|
|
||||||
@ -320,8 +326,8 @@ static int active_connections;
|
|||||||
Local prototypes.
|
Local prototypes.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static char *create_socket_name (char *standard_name);
|
static char *create_socket_name (char *standard_name, int with_homedir);
|
||||||
static gnupg_fd_t create_server_socket (char *name, int is_ssh,
|
static gnupg_fd_t create_server_socket (char *name, int primary,
|
||||||
assuan_sock_nonce_t *nonce);
|
assuan_sock_nonce_t *nonce);
|
||||||
static void create_directories (void);
|
static void create_directories (void);
|
||||||
|
|
||||||
@ -329,6 +335,7 @@ static void agent_init_default_ctrl (ctrl_t ctrl);
|
|||||||
static void agent_deinit_default_ctrl (ctrl_t ctrl);
|
static void agent_deinit_default_ctrl (ctrl_t ctrl);
|
||||||
|
|
||||||
static void handle_connections (gnupg_fd_t listen_fd,
|
static void handle_connections (gnupg_fd_t listen_fd,
|
||||||
|
gnupg_fd_t listen_fd_extra,
|
||||||
gnupg_fd_t listen_fd_ssh);
|
gnupg_fd_t listen_fd_ssh);
|
||||||
static void check_own_socket (void);
|
static void check_own_socket (void);
|
||||||
static int check_for_running_agent (int silent);
|
static int check_for_running_agent (int silent);
|
||||||
@ -498,6 +505,8 @@ cleanup (void)
|
|||||||
done = 1;
|
done = 1;
|
||||||
deinitialize_module_cache ();
|
deinitialize_module_cache ();
|
||||||
remove_socket (socket_name);
|
remove_socket (socket_name);
|
||||||
|
if (opt.extra_socket > 1)
|
||||||
|
remove_socket (socket_name_extra);
|
||||||
remove_socket (socket_name_ssh);
|
remove_socket (socket_name_ssh);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -860,6 +869,11 @@ main (int argc, char **argv )
|
|||||||
# endif
|
# endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case oExtraSocket:
|
||||||
|
opt.extra_socket = 1; /* (1 = points into argv) */
|
||||||
|
socket_name_extra = pargs.r.ret_str;
|
||||||
|
break;
|
||||||
|
|
||||||
case oDebugQuickRandom:
|
case oDebugQuickRandom:
|
||||||
/* Only used by the first stage command line parser. */
|
/* Only used by the first stage command line parser. */
|
||||||
break;
|
break;
|
||||||
@ -1067,7 +1081,8 @@ main (int argc, char **argv )
|
|||||||
else
|
else
|
||||||
{ /* Regular server mode */
|
{ /* Regular server mode */
|
||||||
gnupg_fd_t fd;
|
gnupg_fd_t fd;
|
||||||
gnupg_fd_t fd_ssh;
|
gnupg_fd_t fd_extra = GNUPG_INVALID_FD;
|
||||||
|
gnupg_fd_t fd_ssh = GNUPG_INVALID_FD;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
|
||||||
/* Remove the DISPLAY variable so that a pinentry does not
|
/* Remove the DISPLAY variable so that a pinentry does not
|
||||||
@ -1081,17 +1096,23 @@ main (int argc, char **argv )
|
|||||||
gnupg_unsetenv ("DISPLAY");
|
gnupg_unsetenv ("DISPLAY");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Create the sockets. */
|
/* Create the sockets. */
|
||||||
socket_name = create_socket_name (GPG_AGENT_SOCK_NAME);
|
socket_name = create_socket_name (GPG_AGENT_SOCK_NAME, 1);
|
||||||
fd = create_server_socket (socket_name, 0, &socket_nonce);
|
fd = create_server_socket (socket_name, 1, &socket_nonce);
|
||||||
|
|
||||||
|
if (opt.extra_socket)
|
||||||
|
{
|
||||||
|
socket_name_extra = create_socket_name (socket_name_extra, 0);
|
||||||
|
opt.extra_socket = 2; /* Indicate that it has been malloced. */
|
||||||
|
fd_extra = create_server_socket (socket_name_extra, 0,
|
||||||
|
&socket_nonce_extra);
|
||||||
|
}
|
||||||
|
|
||||||
if (opt.ssh_support)
|
if (opt.ssh_support)
|
||||||
{
|
{
|
||||||
socket_name_ssh = create_socket_name (GPG_AGENT_SSH_SOCK_NAME);
|
socket_name_ssh = create_socket_name (GPG_AGENT_SSH_SOCK_NAME, 1);
|
||||||
fd_ssh = create_server_socket (socket_name_ssh, 1, &socket_nonce_ssh);
|
fd_ssh = create_server_socket (socket_name_ssh, 0, &socket_nonce_ssh);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
fd_ssh = GNUPG_INVALID_FD;
|
|
||||||
|
|
||||||
/* If we are going to exec a program in the parent, we record
|
/* If we are going to exec a program in the parent, we record
|
||||||
the PID, so that the child may check whether the program is
|
the PID, so that the child may check whether the program is
|
||||||
@ -1154,6 +1175,8 @@ main (int argc, char **argv )
|
|||||||
|
|
||||||
*socket_name = 0; /* Don't let cleanup() remove the socket -
|
*socket_name = 0; /* Don't let cleanup() remove the socket -
|
||||||
the child should do this from now on */
|
the child should do this from now on */
|
||||||
|
if (opt.extra_socket)
|
||||||
|
*socket_name_extra = 0;
|
||||||
if (opt.ssh_support)
|
if (opt.ssh_support)
|
||||||
*socket_name_ssh = 0;
|
*socket_name_ssh = 0;
|
||||||
|
|
||||||
@ -1264,7 +1287,7 @@ main (int argc, char **argv )
|
|||||||
#endif /*!HAVE_W32_SYSTEM*/
|
#endif /*!HAVE_W32_SYSTEM*/
|
||||||
|
|
||||||
log_info ("%s %s started\n", strusage(11), strusage(13) );
|
log_info ("%s %s started\n", strusage(11), strusage(13) );
|
||||||
handle_connections (fd, opt.ssh_support ? fd_ssh : GNUPG_INVALID_FD);
|
handle_connections (fd, fd_extra, fd_ssh);
|
||||||
assuan_sock_close (fd);
|
assuan_sock_close (fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1304,7 +1327,7 @@ agent_exit (int rc)
|
|||||||
structure usually identified by an argument named CTRL. This
|
structure usually identified by an argument named CTRL. This
|
||||||
function is called immediately after allocating the control
|
function is called immediately after allocating the control
|
||||||
structure. Its purpose is to setup the default values for that
|
structure. Its purpose is to setup the default values for that
|
||||||
structure. */
|
structure. Note that some values may have already been set. */
|
||||||
static void
|
static void
|
||||||
agent_init_default_ctrl (ctrl_t ctrl)
|
agent_init_default_ctrl (ctrl_t ctrl)
|
||||||
{
|
{
|
||||||
@ -1463,11 +1486,14 @@ get_agent_scd_notify_event (void)
|
|||||||
Pointer to an allocated string with the absolute name of the socket
|
Pointer to an allocated string with the absolute name of the socket
|
||||||
used. */
|
used. */
|
||||||
static char *
|
static char *
|
||||||
create_socket_name (char *standard_name)
|
create_socket_name (char *standard_name, int with_homedir)
|
||||||
{
|
{
|
||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
name = make_filename (opt.homedir, standard_name, NULL);
|
if (with_homedir)
|
||||||
|
name = make_filename (opt.homedir, standard_name, NULL);
|
||||||
|
else
|
||||||
|
name = make_filename (standard_name, NULL);
|
||||||
if (strchr (name, PATHSEP_C))
|
if (strchr (name, PATHSEP_C))
|
||||||
{
|
{
|
||||||
log_error (("'%s' are not allowed in the socket name\n"), PATHSEP_S);
|
log_error (("'%s' are not allowed in the socket name\n"), PATHSEP_S);
|
||||||
@ -1484,11 +1510,11 @@ create_socket_name (char *standard_name)
|
|||||||
|
|
||||||
|
|
||||||
/* Create a Unix domain socket with NAME. Returns the file descriptor
|
/* Create a Unix domain socket with NAME. Returns the file descriptor
|
||||||
or terminates the process in case of an error. Not that this
|
or terminates the process in case of an error. Note that this
|
||||||
function needs to be used for the regular socket first and only
|
function needs to be used for the regular socket first (indicated
|
||||||
then for the ssh socket. */
|
by PRIMARY) and only then for the extra and the ssh sockets. */
|
||||||
static gnupg_fd_t
|
static gnupg_fd_t
|
||||||
create_server_socket (char *name, int is_ssh, assuan_sock_nonce_t *nonce)
|
create_server_socket (char *name, int primary, assuan_sock_nonce_t *nonce)
|
||||||
{
|
{
|
||||||
struct sockaddr_un *serv_addr;
|
struct sockaddr_un *serv_addr;
|
||||||
socklen_t len;
|
socklen_t len;
|
||||||
@ -1531,7 +1557,7 @@ create_server_socket (char *name, int is_ssh, assuan_sock_nonce_t *nonce)
|
|||||||
know the new Assuan socket, the Assuan server and thus the
|
know the new Assuan socket, the Assuan server and thus the
|
||||||
ssh-agent server is not yet operational. This would lead to
|
ssh-agent server is not yet operational. This would lead to
|
||||||
a hang. */
|
a hang. */
|
||||||
if (!is_ssh && !check_for_running_agent (1))
|
if (primary && !check_for_running_agent (1))
|
||||||
{
|
{
|
||||||
log_set_prefix (NULL, JNLIB_LOG_WITH_PREFIX);
|
log_set_prefix (NULL, JNLIB_LOG_WITH_PREFIX);
|
||||||
log_set_file (NULL);
|
log_set_file (NULL);
|
||||||
@ -1980,12 +2006,9 @@ putty_message_thread (void *arg)
|
|||||||
#endif /*HAVE_W32_SYSTEM*/
|
#endif /*HAVE_W32_SYSTEM*/
|
||||||
|
|
||||||
|
|
||||||
/* This is the standard connection thread's main function. */
|
|
||||||
static void *
|
static void *
|
||||||
start_connection_thread (void *arg)
|
start_connection_thread (ctrl_t ctrl)
|
||||||
{
|
{
|
||||||
ctrl_t ctrl = arg;
|
|
||||||
|
|
||||||
if (check_nonce (ctrl, &socket_nonce))
|
if (check_nonce (ctrl, &socket_nonce))
|
||||||
{
|
{
|
||||||
log_error ("handler 0x%lx nonce check FAILED\n",
|
log_error ("handler 0x%lx nonce check FAILED\n",
|
||||||
@ -2009,6 +2032,27 @@ start_connection_thread (void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* This is the standard connection thread's main function. */
|
||||||
|
static void *
|
||||||
|
start_connection_thread_std (void *arg)
|
||||||
|
{
|
||||||
|
ctrl_t ctrl = arg;
|
||||||
|
|
||||||
|
return start_connection_thread (ctrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* This is the extra socket connection thread's main function. */
|
||||||
|
static void *
|
||||||
|
start_connection_thread_extra (void *arg)
|
||||||
|
{
|
||||||
|
ctrl_t ctrl = arg;
|
||||||
|
|
||||||
|
ctrl->restricted = 1;
|
||||||
|
return start_connection_thread (ctrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This is the ssh connection thread's main function. */
|
/* This is the ssh connection thread's main function. */
|
||||||
static void *
|
static void *
|
||||||
start_connection_thread_ssh (void *arg)
|
start_connection_thread_ssh (void *arg)
|
||||||
@ -2037,7 +2081,9 @@ start_connection_thread_ssh (void *arg)
|
|||||||
/* Connection handler loop. Wait for connection requests and spawn a
|
/* Connection handler loop. Wait for connection requests and spawn a
|
||||||
thread after accepting a connection. */
|
thread after accepting a connection. */
|
||||||
static void
|
static void
|
||||||
handle_connections (gnupg_fd_t listen_fd, gnupg_fd_t listen_fd_ssh)
|
handle_connections (gnupg_fd_t listen_fd,
|
||||||
|
gnupg_fd_t listen_fd_extra,
|
||||||
|
gnupg_fd_t listen_fd_ssh)
|
||||||
{
|
{
|
||||||
npth_attr_t tattr;
|
npth_attr_t tattr;
|
||||||
struct sockaddr_un paddr;
|
struct sockaddr_un paddr;
|
||||||
@ -2054,6 +2100,16 @@ handle_connections (gnupg_fd_t listen_fd, gnupg_fd_t listen_fd_ssh)
|
|||||||
HANDLE events[2];
|
HANDLE events[2];
|
||||||
unsigned int events_set;
|
unsigned int events_set;
|
||||||
#endif
|
#endif
|
||||||
|
struct {
|
||||||
|
const char *name;
|
||||||
|
void *(*func) (void *arg);
|
||||||
|
gnupg_fd_t l_fd;
|
||||||
|
} listentbl[] = {
|
||||||
|
{ "std", start_connection_thread_std },
|
||||||
|
{ "extra",start_connection_thread_extra },
|
||||||
|
{ "ssh", start_connection_thread_ssh }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
ret = npth_attr_init(&tattr);
|
ret = npth_attr_init(&tattr);
|
||||||
if (ret)
|
if (ret)
|
||||||
@ -2103,6 +2159,12 @@ handle_connections (gnupg_fd_t listen_fd, gnupg_fd_t listen_fd_ssh)
|
|||||||
FD_ZERO (&fdset);
|
FD_ZERO (&fdset);
|
||||||
FD_SET (FD2INT (listen_fd), &fdset);
|
FD_SET (FD2INT (listen_fd), &fdset);
|
||||||
nfd = FD2INT (listen_fd);
|
nfd = FD2INT (listen_fd);
|
||||||
|
if (listen_fd_extra != GNUPG_INVALID_FD)
|
||||||
|
{
|
||||||
|
FD_SET ( FD2INT(listen_fd_extra), &fdset);
|
||||||
|
if (FD2INT (listen_fd_extra) > nfd)
|
||||||
|
nfd = FD2INT (listen_fd_extra);
|
||||||
|
}
|
||||||
if (listen_fd_ssh != GNUPG_INVALID_FD)
|
if (listen_fd_ssh != GNUPG_INVALID_FD)
|
||||||
{
|
{
|
||||||
FD_SET ( FD2INT(listen_fd_ssh), &fdset);
|
FD_SET ( FD2INT(listen_fd_ssh), &fdset);
|
||||||
@ -2110,6 +2172,10 @@ handle_connections (gnupg_fd_t listen_fd, gnupg_fd_t listen_fd_ssh)
|
|||||||
nfd = FD2INT (listen_fd_ssh);
|
nfd = FD2INT (listen_fd_ssh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
listentbl[0].l_fd = listen_fd;
|
||||||
|
listentbl[1].l_fd = listen_fd_extra;
|
||||||
|
listentbl[2].l_fd = listen_fd_ssh;
|
||||||
|
|
||||||
npth_clock_gettime (&abstime);
|
npth_clock_gettime (&abstime);
|
||||||
abstime.tv_sec += TIMERTICK_INTERVAL;
|
abstime.tv_sec += TIMERTICK_INTERVAL;
|
||||||
|
|
||||||
@ -2172,92 +2238,56 @@ handle_connections (gnupg_fd_t listen_fd, gnupg_fd_t listen_fd_ssh)
|
|||||||
next timeout. */
|
next timeout. */
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!shutdown_pending && FD_ISSET (FD2INT (listen_fd), &read_fdset))
|
if (!shutdown_pending)
|
||||||
{
|
{
|
||||||
|
int idx;
|
||||||
ctrl_t ctrl;
|
ctrl_t ctrl;
|
||||||
|
npth_t thread;
|
||||||
|
|
||||||
plen = sizeof paddr;
|
for (idx=0; idx < DIM(listentbl); idx++)
|
||||||
fd = INT2FD (npth_accept (FD2INT(listen_fd),
|
|
||||||
(struct sockaddr *)&paddr, &plen));
|
|
||||||
if (fd == GNUPG_INVALID_FD)
|
|
||||||
{
|
|
||||||
log_error ("accept failed: %s\n", strerror (errno));
|
|
||||||
}
|
|
||||||
else if ( !(ctrl = xtrycalloc (1, sizeof *ctrl)) )
|
|
||||||
{
|
{
|
||||||
log_error ("error allocating connection control data: %s\n",
|
if (listentbl[idx].l_fd == GNUPG_INVALID_FD)
|
||||||
strerror (errno) );
|
continue;
|
||||||
assuan_sock_close (fd);
|
if (!FD_ISSET (FD2INT (listentbl[idx].l_fd), &read_fdset))
|
||||||
}
|
continue;
|
||||||
else if ( !(ctrl->session_env = session_env_new ()) )
|
|
||||||
{
|
|
||||||
log_error ("error allocating session environment block: %s\n",
|
|
||||||
strerror (errno) );
|
|
||||||
xfree (ctrl);
|
|
||||||
assuan_sock_close (fd);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
npth_t thread;
|
|
||||||
|
|
||||||
ctrl->thread_startup.fd = fd;
|
plen = sizeof paddr;
|
||||||
ret = npth_create (&thread, &tattr,
|
fd = INT2FD (npth_accept (FD2INT(listentbl[idx].l_fd),
|
||||||
start_connection_thread, ctrl);
|
(struct sockaddr *)&paddr, &plen));
|
||||||
if (ret)
|
if (fd == GNUPG_INVALID_FD)
|
||||||
{
|
{
|
||||||
log_error ("error spawning connection handler: %s\n",
|
log_error ("accept failed for %s: %s\n",
|
||||||
strerror (ret));
|
listentbl[idx].name, strerror (errno));
|
||||||
assuan_sock_close (fd);
|
|
||||||
xfree (ctrl);
|
|
||||||
}
|
}
|
||||||
|
else if ( !(ctrl = xtrycalloc (1, sizeof *ctrl)))
|
||||||
}
|
|
||||||
fd = GNUPG_INVALID_FD;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!shutdown_pending && listen_fd_ssh != GNUPG_INVALID_FD
|
|
||||||
&& FD_ISSET ( FD2INT (listen_fd_ssh), &read_fdset))
|
|
||||||
{
|
|
||||||
ctrl_t ctrl;
|
|
||||||
|
|
||||||
plen = sizeof paddr;
|
|
||||||
fd = INT2FD(npth_accept (FD2INT(listen_fd_ssh),
|
|
||||||
(struct sockaddr *)&paddr, &plen));
|
|
||||||
if (fd == GNUPG_INVALID_FD)
|
|
||||||
{
|
|
||||||
log_error ("accept failed for ssh: %s\n", strerror (errno));
|
|
||||||
}
|
|
||||||
else if ( !(ctrl = xtrycalloc (1, sizeof *ctrl)) )
|
|
||||||
{
|
|
||||||
log_error ("error allocating connection control data: %s\n",
|
|
||||||
strerror (errno) );
|
|
||||||
assuan_sock_close (fd);
|
|
||||||
}
|
|
||||||
else if ( !(ctrl->session_env = session_env_new ()) )
|
|
||||||
{
|
|
||||||
log_error ("error allocating session environment block: %s\n",
|
|
||||||
strerror (errno) );
|
|
||||||
xfree (ctrl);
|
|
||||||
assuan_sock_close (fd);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
npth_t thread;
|
|
||||||
|
|
||||||
agent_init_default_ctrl (ctrl);
|
|
||||||
ctrl->thread_startup.fd = fd;
|
|
||||||
ret = npth_create (&thread, &tattr,
|
|
||||||
start_connection_thread_ssh, ctrl);
|
|
||||||
if (ret)
|
|
||||||
{
|
{
|
||||||
log_error ("error spawning ssh connection handler: %s\n",
|
log_error ("error allocating connection data for %s: %s\n",
|
||||||
strerror (ret));
|
listentbl[idx].name, strerror (errno) );
|
||||||
assuan_sock_close (fd);
|
assuan_sock_close (fd);
|
||||||
xfree (ctrl);
|
|
||||||
}
|
}
|
||||||
|
else if ( !(ctrl->session_env = session_env_new ()))
|
||||||
|
{
|
||||||
|
log_error ("error allocating session env block for %s: %s\n",
|
||||||
|
listentbl[idx].name, strerror (errno) );
|
||||||
|
xfree (ctrl);
|
||||||
|
assuan_sock_close (fd);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ctrl->thread_startup.fd = fd;
|
||||||
|
ret = npth_create (&thread, &tattr,
|
||||||
|
listentbl[idx].func, ctrl);
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
log_error ("error spawning connection handler for %s:"
|
||||||
|
" %s\n", listentbl[idx].name, strerror (ret));
|
||||||
|
assuan_sock_close (fd);
|
||||||
|
xfree (ctrl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fd = GNUPG_INVALID_FD;
|
||||||
}
|
}
|
||||||
fd = GNUPG_INVALID_FD;
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup ();
|
cleanup ();
|
||||||
|
@ -504,9 +504,23 @@ start_new_gpg_agent (assuan_context_t *r_ctx,
|
|||||||
err = assuan_transact (ctx, "RESET",
|
err = assuan_transact (ctx, "RESET",
|
||||||
NULL, NULL, NULL, NULL, NULL, NULL);
|
NULL, NULL, NULL, NULL, NULL, NULL);
|
||||||
if (!err)
|
if (!err)
|
||||||
err = send_pinentry_environment (ctx, errsource,
|
{
|
||||||
opt_lc_ctype, opt_lc_messages,
|
err = send_pinentry_environment (ctx, errsource,
|
||||||
session_env);
|
opt_lc_ctype, opt_lc_messages,
|
||||||
|
session_env);
|
||||||
|
if (gpg_err_code (err) == GPG_ERR_FORBIDDEN
|
||||||
|
&& gpg_err_source (err) == GPG_ERR_SOURCE_GPGAGENT)
|
||||||
|
{
|
||||||
|
/* Check whether we are in restricted mode. */
|
||||||
|
if (!assuan_transact (ctx, "GETINFO restricted",
|
||||||
|
NULL, NULL, NULL, NULL, NULL, NULL))
|
||||||
|
{
|
||||||
|
if (verbose)
|
||||||
|
log_info (_("connection to agent is in restricted mode\n"));
|
||||||
|
err = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
assuan_release (ctx);
|
assuan_release (ctx);
|
||||||
|
@ -35,6 +35,12 @@
|
|||||||
#include <errno.h> /* We need errno. */
|
#include <errno.h> /* We need errno. */
|
||||||
#include <gpg-error.h> /* We need gpg_error_t and estream. */
|
#include <gpg-error.h> /* We need gpg_error_t and estream. */
|
||||||
|
|
||||||
|
/* These error codes are used but not defined in the required
|
||||||
|
libgpg-error version. Define them here. */
|
||||||
|
#if GPG_ERROR_VERSION_NUMBER < 0x011200 /* 1.18 */
|
||||||
|
# define GPG_ERR_FORBIDDEN 251
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Hash function used with libksba. */
|
/* Hash function used with libksba. */
|
||||||
#define HASH_FNC ((void (*)(void *, const void*,size_t))gcry_md_write)
|
#define HASH_FNC ((void (*)(void *, const void*,size_t))gcry_md_write)
|
||||||
|
@ -532,6 +532,19 @@ Ignore requests to change the current @code{tty} or X window system's
|
|||||||
@code{DISPLAY} variable respectively. This is useful to lock the
|
@code{DISPLAY} variable respectively. This is useful to lock the
|
||||||
pinentry to pop up at the @code{tty} or display you started the agent.
|
pinentry to pop up at the @code{tty} or display you started the agent.
|
||||||
|
|
||||||
|
|
||||||
|
@anchor{option --extra-socket}
|
||||||
|
@item --extra-socket @var{name}
|
||||||
|
@opindex extra-socket
|
||||||
|
Also listen on native gpg-agent connections on the given socket. The
|
||||||
|
intended use for this extra socket is to setup a Unix domain socket
|
||||||
|
forwarding from a remote machine to this socket on the local machine.
|
||||||
|
A @command{gpg} running on the remote machine may then connect to the
|
||||||
|
local gpg-agent and use its private keys. This allows to decrypt or
|
||||||
|
sign data on a remote machine without exposing the private keys to the
|
||||||
|
remote machine.
|
||||||
|
|
||||||
|
|
||||||
@anchor{option --enable-ssh-support}
|
@anchor{option --enable-ssh-support}
|
||||||
@item --enable-ssh-support
|
@item --enable-ssh-support
|
||||||
@opindex enable-ssh-support
|
@opindex enable-ssh-support
|
||||||
|
Loading…
x
Reference in New Issue
Block a user