# # patch "ChangeLog" # from [d33d68dc607d41683f065b3776e01ee923617466] # to [e6d610afcc4f92bcbeab2aa860fd84ff8a5bfdb8] # # patch "lua.cc" # from [8430784d91bb9e1980222576875130d56bf3403c] # to [e2e91c14e07acc669a5ffb10a9983c5403997cfc] # # patch "lua.hh" # from [10ff3e44271236c23ac4c316bff67e6e2b35a6f9] # to [0d70b46599b54eab35528c97bb129b552d6d0f9c] # # patch "monotone.texi" # from [495c522c60665ce62c24e353f3c2ab6227f1f080] # to [2330c9284da3b0c30bafe492364fb36981097993] # # patch "netsync.cc" # from [502c6ec70bb1fea01a686c02d7569be7c7f28626] # to [11c23b266ccccb4742d2c0ae6502fbca9fccd6c5] # # patch "packet.cc" # from [bfeb9fa42d45b9254137632ae776d1721e1df6c2] # to [bd0eb9d56a0d3845911aa49ed31353a9e40f9fe5] # # patch "packet.hh" # from [19cb7588b015bab35eed74ca84c46ba5195870d5] # to [ec7178c2332473305c0aa7d00c727e338fc7810d] # --- ChangeLog +++ ChangeLog @@ -1,5 +1,13 @@ -2005-05-30 Timothy Brownawell +2005-05-30 Timothy Brownawell + * lua.{cc,hh}: Replace note_netsync_commit with + note_netsync_{revision,cert,pubkey}_received + * packet.{cc,hh}: Callbacks for cert or key written to the database. + * netsync.cc: Use said callbacks, call note_netsync_*_received hooks. + * monotone.texi: Update documentation. + +2005-05-30 Timothy Brownawell + * packet.{cc,hh}, netsync.cc: on_revision_written callback now takes the revision_id as an argument. * lua.{cc,hh}: New Lua hook, note_netsync_commit. --- lua.cc +++ lua.cc @@ -1123,24 +1123,67 @@ } bool -lua_hooks::hook_note_netsync_commit(revision_id const & new_id, - map const & certs) +lua_hooks::hook_note_netsync_revision_received(revision_id const & new_id, + set > > const & certs) { Lua ll(st); ll - .func("note_netsync_commit") + .func("note_netsync_revision_received") .push_str(new_id.inner()()); ll.push_table(); + + typedef set > > cdat; - for (map::const_iterator i = certs.begin(); - i != certs.end(); ++i) + int n=0; + for (cdat::const_iterator i = certs.begin(); i != certs.end(); ++i) { + ll.push_int(n++); + ll.push_table(); + ll.push_str("key"); ll.push_str(i->first()); - ll.push_str(i->second()); ll.set_table(); + ll.push_str("name"); + ll.push_str(i->second.first()); + ll.set_table(); + ll.push_str("value"); + ll.push_str(i->second.second()); + ll.set_table(); + ll.set_table(); } - + ll.call(2, 0); return ll.ok(); } + +bool +lua_hooks::hook_note_netsync_pubkey_received(rsa_keypair_id const & kid) +{ + Lua ll(st); + ll + .func("note_netsync_pubkey_received") + .push_str(kid()); + + ll.call(1, 0); + return ll.ok(); +} + +bool +lua_hooks::hook_note_netsync_cert_received(revision_id const & rid, + rsa_keypair_id const & kid, + cert_name const & name, + cert_value const & value) +{ + Lua ll(st); + ll + .func("note_netsync_cert_received") + .push_str(rid.inner()()) + .push_str(kid()) + .push_str(name()) + .push_str(value()); + + ll.call(4, 0); + return ll.ok(); +} --- lua.hh +++ lua.hh @@ -116,8 +116,16 @@ // notification hooks bool hook_note_commit(revision_id const & new_id, std::map const & certs); - bool hook_note_netsync_commit(revision_id const & new_id, - std::map const & certs); + + bool hook_note_netsync_revision_received(revision_id const & new_id, + std::set > > const & certs); + bool hook_note_netsync_pubkey_received(rsa_keypair_id const & kid); + bool hook_note_netsync_cert_received(revision_id const & rid, + rsa_keypair_id const & kid, + cert_name const & name, + cert_value const & value); }; #endif // __LUA_HH__ --- monotone.texi +++ monotone.texi @@ -5183,12 +5183,30 @@ commit-notification systems such as mailing lists or news services. It should not perform any security-critical operations. address@hidden note_netsync_commit (@var{new_id}, @var{certs}) address@hidden note_netsync_revision_received (@var{new_id}, @var{certs}) -Called by monotone after the version @var{new_id} is recieved through -netsync. Other than the origin of @var{new_id}, this is identical to -the note_commit hook. +Called by monotone after the revision @var{new_id} is recieved through +netsync. @var{certs} is a lua table containing one subtable for each +cert attached to the revision @var{new_id}. These subtables have fields +named "key", "name", and "value", containing the signing key for the cert, +the name of the cert, and the value of the cert.There is no default +definition for this hook. address@hidden note_netsync_cert_received (@var{rev_id}, @var{key}, + @var{name}, @var{value}) + +Called by monotone after a cert is received through netsync, iff the revision +that the cert is attached to was not also received in the same netsync +operation. @var{rev_id} is the revision id that the cert is attached to, address@hidden is the key that the cert is signed with, @var{name} is the name +of the cert, and @var{value} is the cert value.There is no default +definition for this hook. + address@hidden note_netsync_pubkey_received (@var{keyname}) + +Called by monotone after a pubkey is received through netsync. @var{keyname} +is the name of the key received.There is no default definition for this hook. + @item get_branch_key (@var{branchname}) Returns a string which is the name of an @sc{rsa} private key used to sign --- netsync.cc +++ netsync.cc @@ -236,7 +236,9 @@ auto_ptr revision_out_ticker; auto_ptr revision_checked_ticker; - vector written_revisions; + set written_revisions; + set written_keys; + set written_certs; map< std::pair, boost::shared_ptr > merkle_tables; @@ -265,6 +267,8 @@ virtual ~session(); void rev_written_callback(revision_id rid); + void key_written_callback(rsa_keypair_id kid); + void cert_written_callback(cert const & c); id mk_nonce(); void mark_recent_io(); @@ -453,6 +457,10 @@ dbw.set_on_revision_written(boost::bind(&session::rev_written_callback, this, _1)); + dbw.set_on_cert_written(boost::bind(&session::cert_written_callback, + this, _1)); + dbw.set_on_pubkey_written(boost::bind(&session::key_written_callback, + this, _1)); // we will panic here if the user doesn't like urandom and we can't give // them a real entropy-driven random. @@ -481,10 +489,17 @@ session::~session() { - for(vector::iterator i=written_revisions.begin(); + //Keys + for(set::iterator i=written_keys.begin(); + i!=written_keys.end(); ++i) + { + app.lua.hook_note_netsync_pubkey_received(*i); + } + //Revisions + for(set::iterator i=written_revisions.begin(); i!=written_revisions.end(); ++i) { - map certs; + set > > certs; vector< revision > ctmp; app.db.get_revision_certs(*i, ctmp); for (vector< revision >::const_iterator j = ctmp.begin(); @@ -492,18 +507,41 @@ { cert_value vtmp; decode_base64(j->inner().value, vtmp); - certs.insert(make_pair(j->inner().name, vtmp)); + certs.insert(make_pair(j->inner().key, + make_pair(j->inner().name, vtmp))); } - app.lua.hook_note_netsync_commit(*i, certs); + app.lua.hook_note_netsync_revision_received(*i, certs); } + //Certs (not attached to a new revision) + for(set::iterator i=written_certs.begin(); + i!=written_certs.end(); ++i) + { + if(written_revisions.find(i->ident)==written_revisions.end()) + { + cert_value tmp; + decode_base64(i->value, tmp); + app.lua.hook_note_netsync_cert_received(i->ident, i->key, + i->name, tmp); + } + } } void session::rev_written_callback(revision_id rid) { if(revision_checked_ticker.get()) ++(*revision_checked_ticker); - written_revisions.push_back(rid); + written_revisions.insert(rid); } +void session::key_written_callback(rsa_keypair_id kid) +{ + written_keys.insert(kid); +} + +void session::cert_written_callback(cert const & c) +{ + written_certs.insert(c); +} + id session::mk_nonce() { @@ -2443,7 +2481,7 @@ // it's ok if we received something we didn't ask for; it might // be a spontaneous transmission from refinement note_item_arrived(type, item); - + switch (type) { case epoch_item: --- packet.cc +++ packet.cc @@ -441,7 +441,28 @@ on_revision_written=x; } +void +packet_consumer::set_on_cert_written(boost::function1 const & x) +{ + on_cert_written=x; +} +void +packet_consumer::set_on_pubkey_written(boost::function1 + const & x) +{ + on_pubkey_written=x; +} + +void +packet_consumer::set_on_privkey_written(boost::function1 + const & x) +{ + on_privkey_written=x; +} + + struct packet_db_writer::impl { app_state & app; @@ -914,6 +935,7 @@ if (pimpl->revision_exists_in_db(revision_id(t.inner().ident))) { pimpl->app.db.put_revision_cert(t); + if(on_cert_written) on_cert_written(t.inner()); } else { @@ -948,7 +970,10 @@ return; } if (! pimpl->app.db.public_key_exists(ident)) - pimpl->app.db.put_key(ident, k); + { + pimpl->app.db.put_key(ident, k); + if(on_pubkey_written) on_pubkey_written(ident); + } else { base64 tmp; @@ -972,7 +997,10 @@ return; } if (! pimpl->app.db.private_key_exists(ident)) - pimpl->app.db.put_key(ident, k); + { + pimpl->app.db.put_key(ident, k); + if(on_privkey_written) on_privkey_written(ident); + } else L(F("skipping existing private key %s\n") % ident); ++(pimpl->count); @@ -1034,7 +1062,32 @@ on_revision_written=x; pimpl->writer.set_on_revision_written(x); } + void +packet_db_valve::set_on_cert_written(boost::function1 const & x) +{ + on_cert_written=x; + pimpl->writer.set_on_cert_written(x); +} + +void +packet_db_valve::set_on_pubkey_written(boost::function1 + const & x) +{ + on_pubkey_written=x; + pimpl->writer.set_on_pubkey_written(x); +} + +void +packet_db_valve::set_on_privkey_written(boost::function1 + const & x) +{ + on_privkey_written=x; + pimpl->writer.set_on_privkey_written(x); +} + +void packet_db_valve::consume_file_data(file_id const & ident, file_data const & dat) { --- packet.hh +++ packet.hh @@ -38,9 +38,19 @@ { protected: boost::function1 on_revision_written; + boost::function1 on_cert_written; + boost::function1 on_pubkey_written; + boost::function1 on_privkey_written; public: - virtual void set_on_revision_written(boost::function1 const & x); + virtual void set_on_revision_written(boost::function1 + const & x); + virtual void set_on_cert_written(boost::function1 + const & x); + virtual void set_on_pubkey_written(boost::function1 + const & x); + virtual void set_on_privkey_written(boost::function1 + const & x); virtual ~packet_consumer() {} virtual void consume_file_data(file_id const & ident, @@ -162,7 +172,14 @@ packet_db_valve(app_state & app, bool take_keys = false); virtual ~packet_db_valve(); - virtual void set_on_revision_written(boost::function1 const & x); + virtual void set_on_revision_written(boost::function1 + const & x); + virtual void set_on_cert_written(boost::function1 + const & x); + virtual void set_on_pubkey_written(boost::function1 + const & x); + virtual void set_on_privkey_written(boost::function1 + const & x); virtual void consume_file_data(file_id const & ident, file_data const & dat); virtual void consume_file_delta(file_id const & id_old,