# # # patch "app_state.hh" # from [2a5bc31705ec0c67381e3f442dcbdf8029bdc81b] # to [22dc5f60fa3d331fb65a4ba92d6f18235900054d] # # patch "cmd_key_cert.cc" # from [674911e6cc5aa00ef03a3552240deb787c6aaab3] # to [83c2290f2212fdc8f1f5bf7c3f7c09b76b074ff0] # # patch "database.cc" # from [7c32fac2c58b7babc6e760ba146862f2baf3f6b9] # to [f2b3da8910f19eaaa8af403cc7b41429866c0f68] # # patch "database.hh" # from [e15e46d3bbc5714ba567813e28157f3f7e5a2278] # to [db3eba0e6cb68d5fa4da20c346bebd2bc6c6ef51] # # patch "key_store.cc" # from [625800e8c5ef8a52e7101f72c77c4674e9bda147] # to [94f2aac8313c841745ffe7caadc284f57d6cdd88] # # patch "key_store.hh" # from [4553714cdb2de487cc192c43e34a858fb0d0bf57] # to [a5ab423522918bb9c0cc828e6658b2c88ef88947] # # patch "keys.cc" # from [8608e18b9d703bf601c723f8694c3a99644c83a9] # to [dd5a511fcd817f152489a4892c1c6cbf1b2232e2] # # patch "ssh_agent.cc" # from [181ea122c65e0e916d87ed91df9a63120e667a42] # to [b16db7de9029559a0013c95dc49b985e12fceeeb] # # patch "ssh_agent.hh" # from [91380e8cfbaddc9dd86e1deea61a0f8d32b29b28] # to [c0c03bdb37905e1e6bbf8350a00fc68b0d83611b] # ============================================================ --- app_state.hh 2a5bc31705ec0c67381e3f442dcbdf8029bdc81b +++ app_state.hh 22dc5f60fa3d331fb65a4ba92d6f18235900054d @@ -21,9 +21,7 @@ class lua_hooks; #include "project.hh" #include "vocab.hh" #include "work.hh" -#include "ssh_agent.hh" - // This class is supposed to hold all (or.. well, most) of the state // of the application, barring some unfortunate static objects like // the debugging / logging system and the command objects, for the @@ -37,7 +35,6 @@ public: database db; key_store keys; workspace work; - ssh_agent agent; options opts; ============================================================ --- cmd_key_cert.cc 674911e6cc5aa00ef03a3552240deb787c6aaab3 +++ cmd_key_cert.cc 83c2290f2212fdc8f1f5bf7c3f7c09b76b074ff0 @@ -13,15 +13,10 @@ #include #include -#include "cert.hh" #include "charset.hh" #include "cmd.hh" #include "app_state.hh" #include "keys.hh" -#include "transforms.hh" -#include "ssh_agent.hh" -#include "botan/pipe.h" -#include "botan/rsa.h" using std::cout; using std::ostream_iterator; @@ -29,9 +24,6 @@ using std::ofstream; using std::set; using std::string; using std::ofstream; -using boost::shared_ptr; -using Botan::Pipe; -using Botan::RSA_PrivateKey; CMD(genkey, "genkey", "", CMD_REF(key_and_cert), N_("KEYID"), N_("Generates an RSA key-pair"), @@ -114,33 +106,15 @@ CMD(ssh_agent_export, "ssh_agent_export" throw usage(execid); rsa_keypair_id id; - keypair key; get_user_key(id, app.opts, app.lua, app.keys, app.db); - app.keys.get_key_pair(id, key); - shared_ptr priv = get_private_key(app.keys, id, key.priv); - utf8 new_phrase; - get_passphrase(new_phrase, id, true, false); - Pipe p; - p.start_msg(); - if (new_phrase().length()) - { - Botan::PKCS8::encrypt_key(*priv, - p, - new_phrase(), - "PBE-PKCS5v20(SHA-1,TripleDES/CBC)"); - } - else - { - Botan::PKCS8::encode(*priv, p); - } - string decoded_key = p.read_all_as_string(); + if (args.size() == 0) - cout << decoded_key; + app.keys.export_key_for_agent(id, cout); else { string external_path = system_path(idx(args, 0)).as_external(); ofstream fout(external_path.c_str(), ofstream::out); - fout << decoded_key; + app.keys.export_key_for_agent(id, fout); } } @@ -153,11 +127,8 @@ CMD(ssh_agent_add, "ssh_agent_add", "", throw usage(execid); rsa_keypair_id id; - keypair key; get_user_key(id, app.opts, app.lua, app.keys, app.db); - app.keys.get_key_pair(id, key); - shared_ptr priv = get_private_key(app.keys, id, key.priv); - app.agent.add_identity(*priv, id()); + app.keys.add_key_to_agent(id); } CMD(cert, "cert", "", CMD_REF(key_and_cert), ============================================================ --- database.cc 7c32fac2c58b7babc6e760ba146862f2baf3f6b9 +++ database.cc f2b3da8910f19eaaa8af403cc7b41429866c0f68 @@ -185,9 +185,13 @@ class database_impl { friend class database; + // for scoped_ptr's sake +public: database_impl(); ~database_impl(); +private: + // // --== Opening the database and schema checking ==-- // @@ -414,9 +418,7 @@ database::~database() {} database::~database() -{ - delete imp; -} +{} void database::set_filename(system_path const & file) @@ -3718,9 +3720,9 @@ conditional_transaction_guard::~conditio if (!acquired) return; if (committed) - imp->commit_transaction(); + db.imp->commit_transaction(); else - imp->rollback_transaction(); + db.imp->rollback_transaction(); } void @@ -3728,15 +3730,15 @@ conditional_transaction_guard::acquire() { I(!acquired); acquired = true; - imp->begin_transaction(exclusive); + db.imp->begin_transaction(exclusive); } void conditional_transaction_guard::do_checkpoint() { I(acquired); - imp->commit_transaction(); - imp->begin_transaction(exclusive); + db.imp->commit_transaction(); + db.imp->begin_transaction(exclusive); checkpointed_calls = 0; checkpointed_bytes = 0; } @@ -3745,7 +3747,7 @@ conditional_transaction_guard::maybe_che conditional_transaction_guard::maybe_checkpoint(size_t nbytes) { I(acquired); - checkpointed_calls += 1; + checkpointed_calls += 1; checkpointed_bytes += nbytes; if (checkpointed_calls >= checkpoint_batch_size || checkpointed_bytes >= checkpoint_batch_bytes) ============================================================ --- database.hh e15e46d3bbc5714ba567813e28157f3f7e5a2278 +++ database.hh db3eba0e6cb68d5fa4da20c346bebd2bc6c6ef51 @@ -13,6 +13,7 @@ #include "vector.hh" #include #include +#include #include "vocab.hh" #include "roster.hh" @@ -441,7 +442,7 @@ private: hexenc const & id, cert_name const & name, cert_value const & val); private: - database_impl *imp; + boost::scoped_ptr imp; lua_hooks & lua; }; @@ -555,7 +556,7 @@ class conditional_transaction_guard class conditional_transaction_guard { - database_impl * imp; + database & db; size_t const checkpoint_batch_size; size_t const checkpoint_batch_bytes; size_t checkpointed_calls; @@ -564,10 +565,10 @@ public: bool acquired; bool const exclusive; public: - conditional_transaction_guard(database & d, bool exclusive=true, + conditional_transaction_guard(database & db, bool exclusive=true, size_t checkpoint_batch_size=1000, size_t checkpoint_batch_bytes=0xfffff) - : imp(d.imp), + : db(db), checkpoint_batch_size(checkpoint_batch_size), checkpoint_batch_bytes(checkpoint_batch_bytes), checkpointed_calls(0), ============================================================ --- key_store.cc 625800e8c5ef8a52e7101f72c77c4674e9bda147 +++ key_store.cc 94f2aac8313c841745ffe7caadc284f57d6cdd88 @@ -9,6 +9,7 @@ #include "app_state.hh" #include "transforms.hh" #include "constants.hh" +#include "ssh_agent.hh" #include "botan/botan.h" #include "botan/rsa.h" @@ -23,6 +24,7 @@ using std::vector; using std::string; using std::vector; +using boost::scoped_ptr; using boost::shared_ptr; using boost::shared_dynamic_cast; @@ -50,6 +52,9 @@ class key_store_state pair, shared_ptr > > signers; + // Initialized when first required. + scoped_ptr agent; + key_store_state(app_state & app) : have_read(false), app(app) {} @@ -61,6 +66,14 @@ public: // can get at it. bool put_key_pair_memory(rsa_keypair_id const & ident, keypair const & kp); + + // wrapper around accesses to agent, initializes as needed + ssh_agent & get_agent() + { + if (!agent) + agent.reset(new ssh_agent); + return *agent; + } }; namespace @@ -121,9 +134,7 @@ key_store::~key_store() } key_store::~key_store() -{ - delete s; -} +{} void key_store::set_key_dir(system_path const & kd) @@ -460,7 +471,7 @@ key_store::make_signature(database & db, db.put_key(id, key.pub); string sig_string; - ssh_agent & agent = s->app.agent; + ssh_agent & agent = s->get_agent(); //sign with ssh-agent (if connected) N(agent.connected() || opt_ssh_sign != "only", @@ -561,6 +572,47 @@ key_store::make_signature(database & db, } // +// Interoperation with ssh-agent (see also above) +// + +void +key_store::add_key_to_agent(rsa_keypair_id const & id) +{ + ssh_agent & agent = s->get_agent(); + N(agent.connected(), + F("no ssh-agent is available, cannot add key '%s'") % id); + + keypair key; + get_key_pair(id, key); + + shared_ptr priv = get_private_key(*this, id, key.priv); + agent.add_identity(*priv, id()); +} + +void +key_store::export_key_for_agent(rsa_keypair_id const & id, + std::ostream & os) +{ + keypair key; + get_key_pair(id, key); + shared_ptr priv = get_private_key(*this, id, key.priv); + utf8 new_phrase; + get_passphrase(new_phrase, id, true, false); + + Pipe p(new Botan::DataSink_Stream(os)); + p.start_msg(); + if (new_phrase().length()) + Botan::PKCS8::encrypt_key(*priv, + p, + new_phrase(), + "PBE-PKCS5v20(SHA-1,TripleDES/CBC)"); + else + Botan::PKCS8::encode(*priv, p); + p.end_msg(); +} + + +// // Migration from old databases // ============================================================ --- key_store.hh 4553714cdb2de487cc192c43e34a858fb0d0bf57 +++ key_store.hh a5ab423522918bb9c0cc828e6658b2c88ef88947 @@ -1,6 +1,8 @@ #ifndef __KEY_STORE_H__ #define __KEY_STORE_H__ +#include +#include #include "vector.hh" #include "vocab.hh" #include "paths.hh" @@ -14,7 +16,7 @@ private: class key_store { private: - key_store_state * s; + boost::scoped_ptr s; void get_key_file(rsa_keypair_id const & ident, system_path & file); void write_key(rsa_keypair_id const & ident); @@ -68,6 +70,12 @@ public: std::string const & tosign, base64 & signature); + // Interoperation with ssh-agent + + void add_key_to_agent(rsa_keypair_id const & id); + void export_key_for_agent(rsa_keypair_id const & id, + std::ostream & os); + // Migration from old databases void migrate_old_key_pair(rsa_keypair_id const & id, ============================================================ --- keys.cc 8608e18b9d703bf601c723f8694c3a99644c83a9 +++ keys.cc dd5a511fcd817f152489a4892c1c6cbf1b2232e2 @@ -34,7 +34,6 @@ #include "ui.hh" #include "cert.hh" #include "charset.hh" -#include "ssh_agent.hh" #include "database.hh" #include "options.hh" ============================================================ --- ssh_agent.cc 181ea122c65e0e916d87ed91df9a63120e667a42 +++ ssh_agent.cc b16db7de9029559a0013c95dc49b985e12fceeeb @@ -276,14 +276,12 @@ ssh_agent::ssh_agent() // ssh_agent::ssh_agent() - : s(new ssh_agent_state()) + : s(new ssh_agent_state) { } ssh_agent::~ssh_agent() -{ - delete s; -} +{} bool ssh_agent::connected() ============================================================ --- ssh_agent.hh 91380e8cfbaddc9dd86e1deea61a0f8d32b29b28 +++ ssh_agent.hh c0c03bdb37905e1e6bbf8350a00fc68b0d83611b @@ -11,6 +11,7 @@ #define __SSH_AGENT_H__ #include "vector.hh" +#include namespace Botan { @@ -33,7 +34,7 @@ private: bool connected(); private: - ssh_agent_state * s; + boost::scoped_ptr s; }; // Local Variables: