The unified diff between revisions [15ff38c4..] and [8032bf83..] is displayed below. It can also be downloaded as a raw diff.
#
#
# patch "cmd_netsync.cc"
# from [1c9f724505164da0026f77e4e81010fddc81faad]
# to [92564b21090c2ebc23734588bcaad5a6740b1c2f]
#
# patch "key_store.cc"
# from [510eb02eab491fd9e79c49fcfcf5e6efa145872f]
# to [5c423e17442795e5cd6ca41ddc2c041e5ac5e553]
#
# patch "key_store.hh"
# from [a2cba22c7534941db07838f8f7b9e3abede66cce]
# to [86b0cfb3002761e38f91aa1b2b696d604a6bc674]
#
# patch "options_list.hh"
# from [e5965106f0af04336b92b0c0c8ca64148c5ad931]
# to [8432925aa61ab0032d712f7a7fbb043b109f7bcb]
#
============================================================
--- cmd_netsync.cc 1c9f724505164da0026f77e4e81010fddc81faad
+++ cmd_netsync.cc 92564b21090c2ebc23734588bcaad5a6740b1c2f
@@ -237,6 +237,39 @@ CMD(push, "push", "", CMD_REF(network),
client_voice, source_role, info);
}
+CMD_AUTOMATE(push, N_("[ADDRESS[:PORTNUMBER] [PATTERN ...]]"),
+ N_("Pushes branches to a netsync server"),
+ "",
+ options::opts::set_default | options::opts::exclude |
+ options::opts::key_to_push | options::opts::do_not_enforce_ssh_agent)
+{
+ database db(app);
+ key_store keys(app);
+ project_t project(db);
+
+ netsync_connection_info info;
+ extract_client_connection_info(app.opts, app.lua, db, keys, args, info);
+
+ if (app.opts.signing_key() != "" && !app.opts.do_not_enforce_ssh_agent)
+ {
+ // enforce that any command which needs to encrypt a private key later on
+ // uses the ssh_agent to do the task, because we cannot handle password
+ // prompts over stdio. basically this is the same as giving --ssh-sign=only
+ // as option to stdio, but it is more explicit. however, this also leaves
+ // the opportunity of giving a possible passphrase via the get_passphrase
+ // lua hook, because the ssh agent is _always_ used, but its a reasonable
+ // trade-off
+ keys.enforce_ssh_agent();
+
+ N(keys.agent_knows_key(app.opts.signing_key),
+ F("key '%s' is unknown to the running ssh-agent instance")
+ % app.opts.signing_key);
+ }
+
+ run_netsync_protocol(app.opts, app.lua, project, keys,
+ client_voice, source_role, info);
+}
+
CMD(pull, "pull", "", CMD_REF(network),
N_("[ADDRESS[:PORTNUMBER] [PATTERN ...]]"),
N_("Pulls branches from a netsync server"),
@@ -262,7 +295,8 @@ CMD_AUTOMATE(pull, N_("[ADDRESS[:PORTNUM
CMD_AUTOMATE(pull, N_("[ADDRESS[:PORTNUMBER] [PATTERN ...]]"),
N_("Pulls branches from a netsync server"),
"",
- options::opts::set_default | options::opts::exclude)
+ options::opts::set_default | options::opts::exclude |
+ options::opts::do_not_enforce_ssh_agent)
{
database db(app);
key_store keys(app);
@@ -272,9 +306,22 @@ CMD_AUTOMATE(pull, N_("[ADDRESS[:PORTNUM
extract_client_connection_info(app.opts, app.lua, db, keys,
args, info, false);
- if (app.opts.signing_key() == "")
- P(F("doing anonymous pull; use -kKEYNAME if you need authentication"));
+ if (app.opts.signing_key() != "" && !app.opts.do_not_enforce_ssh_agent)
+ {
+ // enforce that any command which needs to encrypt a private key later on
+ // uses the ssh_agent to do the task, because we cannot handle password
+ // prompts over stdio. basically this is the same as giving --ssh-sign=only
+ // as option to stdio, but it is more explicit. however, this also leaves
+ // the opportunity of giving a possible passphrase via the get_passphrase
+ // lua hook, because the ssh agent is _always_ used, but its a reasonable
+ // trade-off
+ keys.enforce_ssh_agent();
+ N(keys.agent_knows_key(app.opts.signing_key),
+ F("key '%s' is unknown to the running ssh-agent instance")
+ % app.opts.signing_key);
+ }
+
run_netsync_protocol(app.opts, app.lua, project, keys,
client_voice, sink_role, info);
}
@@ -285,7 +332,7 @@ CMD(sync, "sync", "", CMD_REF(network),
N_("This synchronizes branches that match the pattern given in PATTERN "
"with the netsync server at the address ADDRESS."),
options::opts::set_default | options::opts::exclude |
- options::opts::key_to_push)
+ options::opts::key_to_push | options::opts::do_not_enforce_ssh_agent)
{
database db(app);
key_store keys(app);
@@ -305,6 +352,39 @@ CMD(sync, "sync", "", CMD_REF(network),
client_voice, source_and_sink_role, info);
}
+CMD_AUTOMATE(sync, N_("[ADDRESS[:PORTNUMBER] [PATTERN ...]]"),
+ N_("Synchronizes branches with a netsync server"),
+ "",
+ options::opts::set_default | options::opts::exclude |
+ options::opts::key_to_push)
+{
+ database db(app);
+ key_store keys(app);
+ project_t project(db);
+
+ netsync_connection_info info;
+ extract_client_connection_info(app.opts, app.lua, db, keys, args, info);
+
+ if (app.opts.signing_key() != "" && !app.opts.do_not_enforce_ssh_agent)
+ {
+ // enforce that any command which needs to encrypt a private key later on
+ // uses the ssh_agent to do the task, because we cannot handle password
+ // prompts over stdio. basically this is the same as giving --ssh-sign=only
+ // as option to stdio, but it is more explicit. however, this also leaves
+ // the opportunity of giving a possible passphrase via the get_passphrase
+ // lua hook, because the ssh agent is _always_ used, but its a reasonable
+ // trade-off
+ keys.enforce_ssh_agent();
+
+ N(keys.agent_knows_key(app.opts.signing_key),
+ F("key '%s' is unknown to the running ssh-agent instance")
+ % app.opts.signing_key);
+ }
+
+ run_netsync_protocol(app.opts, app.lua, project, keys,
+ client_voice, source_and_sink_role, info);
+}
+
class dir_cleanup_helper
{
public:
============================================================
--- key_store.cc 510eb02eab491fd9e79c49fcfcf5e6efa145872f
+++ key_store.cc 5c423e17442795e5cd6ca41ddc2c041e5ac5e553
@@ -710,7 +710,31 @@ key_store::export_key_for_agent(rsa_keyp
p.end_msg();
}
+void
+key_store::enforce_ssh_agent()
+{
+ ssh_agent & agent = s->get_agent();
+ N(agent.connected(),
+ F("this command enforces the only usage of ssh_agent, "
+ "but no ssh-agent is available."));
+ if (s->ssh_sign_mode != "only")
+ {
+ W(F("enforcing the only usage of ssh_agent"));
+ const_cast<std::string &>(s->ssh_sign_mode) = "only";
+ }
+}
+bool
+key_store::agent_knows_key(rsa_keypair_id const & ident)
+{
+ keypair keyp;
+ N(maybe_get_key_pair(ident, keyp),
+ F("no keypair for '%s' in keyring") % ident);
+
+ ssh_agent & agent = s->get_agent();
+ return agent.has_key(keyp);
+}
+
//
// Migration from old databases
//
============================================================
--- key_store.hh a2cba22c7534941db07838f8f7b9e3abede66cce
+++ key_store.hh 86b0cfb3002761e38f91aa1b2b696d604a6bc674
@@ -82,6 +82,8 @@ public:
void add_key_to_agent(rsa_keypair_id const & id);
void export_key_for_agent(rsa_keypair_id const & id,
std::ostream & os);
+ void enforce_ssh_agent();
+ bool agent_knows_key(rsa_keypair_id const & ident);
// Migration from old databases
============================================================
--- options_list.hh e5965106f0af04336b92b0c0c8ca64148c5ad931
+++ options_list.hh 8432925aa61ab0032d712f7a7fbb043b109f7bcb
@@ -80,6 +80,17 @@ OPT(automate_stdio_size, "automate-stdio
}
#endif
+OPT(do_not_enforce_ssh_agent, "do-not-enforce-ssh-agent", bool, false,
+ gettext_noop("do not enforce the usage of ssh-agent. enabling this is "
+ "highly discouraged if you run this command over stdio "
+ "as it may prompt for a key password which cannot be "
+ "handled."))
+#ifdef option_bodies
+{
+ do_not_enforce_ssh_agent = true;
+}
+#endif
+
OPTSET(bind_opts)
OPTVAR(bind_opts, std::list<utf8>, bind_uris, )
OPTVAR(bind_opts, bool, bind_stdio, false)