# # # patch "cmd_automate.cc" # from [12c3763af3ff4acaca3cd0806fdd3cf783926f0b] # to [1cdf64eae5a36be698d427ab2172a7e4d186f2ca] # # patch "cmd_netsync.cc" # from [f10b381a9c501068f79ab5af2b8f59d762417105] # to [352b0957e54298dfa1de185aaa125f105204c762] # # patch "key_store.cc" # from [795a3751858db90c5d0fbe8b7e1aa491511290a8] # to [b78c703dc6b4f9b29b55526df73c09c60185cdc8] # # patch "monotone.texi" # from [728eac7544855d0e39fa9093b514c09ef0865a64] # to [0894845f1d2b54d4815b1c8b951d0efecaa2843c] # # patch "network/automate_session.cc" # from [eeb9c7d6c3b128d173544ea8210bb6efadb1a3cf] # to [69fcc9df864eb5edfdd8e0472846d7698add6a3b] # # patch "options_list.hh" # from [42b7d4abf66f0eb69a94d8a4517616841ea13757] # to [85e9dc9fe8a836c20eed806b14253ca0a557c199] # ============================================================ --- cmd_automate.cc 12c3763af3ff4acaca3cd0806fdd3cf783926f0b +++ cmd_automate.cc 1cdf64eae5a36be698d427ab2172a7e4d186f2ca @@ -215,6 +215,8 @@ CMD_AUTOMATE_NO_STDIO(stdio, "", // immediately if a version discrepancy exists db.ensure_open(); + // disable user prompts, f.e. for password decryption + app.opts.non_interactive = true; options original_opts = app.opts; automate_ostream os(output, app.opts.automate_stdio_size); @@ -364,6 +366,9 @@ LUAEXT(mtn_automate, ) args.push_back(next_arg); } + // disable user prompts, f.e. for password decryption + app_p->opts.non_interactive = true; + options::options_type opts; opts = options::opts::all_options() - options::opts::globals(); opts.instantiate(&app_p->opts).reset(); ============================================================ --- cmd_netsync.cc f10b381a9c501068f79ab5af2b8f59d762417105 +++ cmd_netsync.cc 352b0957e54298dfa1de185aaa125f105204c762 @@ -242,6 +242,8 @@ CMD_AUTOMATE_NO_STDIO(remote_stdio, if (args.size() > 1) throw usage(execid); + app.opts.non_interactive = true; + database db(app); key_store keys(app); project_t project(db); @@ -463,7 +465,7 @@ CMD(push, "push", "", CMD_REF(network), extract_client_connection_info(app.opts, app.lua, db, keys, project, args, info); - run_netsync_protocol(app.opts, app.lua, project, keys, + run_netsync_protocol(app, app.opts, app.lua, project, keys, client_voice, source_role, info); } @@ -505,7 +507,7 @@ CMD(pull, "pull", "", CMD_REF(network), if (!keys.have_signing_key()) P(F("doing anonymous pull; use -kKEYNAME if you need authentication")); - run_netsync_protocol(app.opts, app.lua, project, keys, + run_netsync_protocol(app, app.opts, app.lua, project, keys, client_voice, sink_role, info); } @@ -552,7 +554,7 @@ CMD(sync, "sync", "", CMD_REF(network), workspace work(app, true); } - run_netsync_protocol(app.opts, app.lua, project, keys, + run_netsync_protocol(app, app.opts, app.lua, project, keys, client_voice, source_and_sink_role, info); } ============================================================ --- key_store.cc 795a3751858db90c5d0fbe8b7e1aa491511290a8 +++ key_store.cc b78c703dc6b4f9b29b55526df73c09c60185cdc8 @@ -65,6 +65,7 @@ struct key_store_state { system_path const key_dir; string const ssh_sign_mode; + bool non_interactive; bool have_read; lua_hooks & lua; key_map keys; @@ -82,6 +83,7 @@ struct key_store_state key_store_state(app_state & app) : key_dir(app.opts.key_dir), ssh_sign_mode(app.opts.ssh_sign), + non_interactive(app.opts.non_interactive), have_read(false), lua(app.lua) { #if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,7,7) @@ -543,16 +545,23 @@ key_store_state::decrypt_private_key(key utf8 phrase; string lua_phrase; - // See whether a lua hook will tell us the passphrase. key_identity_info identity; identity.id = id; identity.given_name = name; - if (!force_from_user && lua.hook_get_passphrase(identity, lua_phrase)) - phrase = utf8(lua_phrase, origin::user); - else - get_passphrase(phrase, name, id, false, false); + // See whether a lua hook will tell us the passphrase. + if ((!force_from_user || non_interactive) && + lua.hook_get_passphrase(identity, lua_phrase)) + { + phrase = utf8(lua_phrase, origin::user); + } + else if (!non_interactive) + { + get_passphrase(phrase, name, id, false, false); + } + int cycles = 1; + for (;;) try { @@ -568,9 +577,9 @@ key_store_state::decrypt_private_key(key { L(FL("decrypt_private_key: failure %d to load encrypted key: %s") % cycles % e.what()); - E(cycles <= 3, origin::no_fault, - F("failed to decrypt old private RSA key, " - "probably incorrect passphrase")); + E(cycles <= 3 && !non_interactive, origin::no_fault, + F("failed to decrypt old private RSA key, probably incorrect " + "passphrase or missing 'get_passphrase' lua hook")); get_passphrase(phrase, name, id, false, false); cycles++; ============================================================ --- monotone.texi 728eac7544855d0e39fa9093b514c09ef0865a64 +++ monotone.texi 0894845f1d2b54d4815b1c8b951d0efecaa2843c @@ -8000,6 +8000,12 @@ @section Automation Trying to run the @code{automate stdio} or @code{automate remote_stdio} sub-commands will exit the particular command with return code "1". address@hidden Notes: + +Keyboard interaction is disabled, just as if @option{--non-interactive} is +specified. Actions which require operations on password-encrypted private keys +will therefor fail unless the @code{get_passphrase} hook is set up locally. + @item Multiple streams The multiple stream encoding allows the output of errors and warnings to be @@ -8049,6 +8055,11 @@ @section Automation configured to include every command which should be executable over this interface. +For both, the client and the server, keyboard interaction is disabled, +just as if @option{--non-interactive} is specified. Actions which require +operations on password-encrypted private keys will therefor fail unless the address@hidden hook is set up locally and / or remotely. + @end table @item mtn automate remote @option{--remote-stdio-host=host} @var{command} @var{args-and-opts} @@ -8103,6 +8114,11 @@ @section Automation configured to include every command which should be executable over this interface. +Keyboard interaction is disabled on the server, just as if address@hidden would have been specified on server startup. +Actions which require operations on password-encrypted private keys will +therefor fail unless a @code{get_passphrase} hook is set up remotely. + @end table @item mtn automate genkey @var{name} @var{passphrase} ============================================================ --- network/automate_session.cc eeb9c7d6c3b128d173544ea8210bb6efadb1a3cf +++ network/automate_session.cc 69fcc9df864eb5edfdd8e0472846d7698add6a3b @@ -139,6 +139,8 @@ bool automate_session::do_work(transacti } case automate_command_cmd: { + // disable user prompts, f.e. for password decryption + app.opts.non_interactive = true; options original_opts = app.opts; vector in_args; ============================================================ --- options_list.hh 42b7d4abf66f0eb69a94d8a4517616841ea13757 +++ options_list.hh 85e9dc9fe8a836c20eed806b14253ca0a557c199 @@ -91,17 +91,6 @@ 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, bind_uris, ) OPTVAR(bind_opts, bool, bind_stdio, false) @@ -472,6 +461,13 @@ GOPT(ignore_suspend_certs, "ignore-suspe } #endif +GOPT(non_interactive, "non-interactive", bool, false, + gettext_noop("do not prompt the user for input")) +#ifdef option_bodies +{ + non_interactive = true; +} +#endif OPTVAR(key, external_key_name, signing_key, ) OPTION(globals, key, true, "key,k",