# # # patch "netsync.cc" # from [ed3a26c1a06ca9dd90261cbec4ba82bb57c79ef0] # to [c527128f45e61964ab7419054f9d24963a1a819e] # # patch "network/netsync_session.cc" # from [d29ead19e030ce5d2f3d9072f4302ad691b0e967] # to [3c16b8a8db73617c18ce23ddad491afceb64fdd8] # # patch "network/netsync_session.hh" # from [e848afaf9518a827735efc982ebe5ca6f3ed1d57] # to [5d914d855e5f2b486876db5b997d8c65e8751cd3] # # patch "network/reactor.cc" # from [706efdfe2fec0191b90c598fbbc8c1d661bb98c0] # to [fa961bc15a1d0a1a6df66d04b2a57ca63941af34] # # patch "network/session.cc" # from [a462c9e3e503442b765ca70488c1c1736215b931] # to [822feddec150c3f60ea3ceee58a1eb0557a22964] # # patch "network/session.hh" # from [4c73ddc1f08b1609a8150e6831664bb52efca02f] # to [1bf5b381aed995a946253357f8850523ce288021] # # patch "network/wrapped_session.cc" # from [4441e6888f140109a33da720a6424b460d51e95d] # to [fc865eb889c81d81330a98726cc3e72f1002297b] # # patch "network/wrapped_session.hh" # from [a280328f066580ee9cd81d5d2a194d6bc7e691da] # to [4110bd6a10485e7114abf283f968efcd27c4037a] # ============================================================ --- netsync.cc ed3a26c1a06ca9dd90261cbec4ba82bb57c79ef0 +++ netsync.cc c527128f45e61964ab7419054f9d24963a1a819e @@ -122,7 +122,8 @@ call_server(options & opts, shared_ptr sess(new session(opts, lua, project, keys, client_voice, info.client.unparsed(), server)); - shared_ptr wrapped(new netsync_session(opts, lua, project, + shared_ptr wrapped(new netsync_session(sess.get(), + opts, lua, project, keys, role, info.client.include_pattern, info.client.exclude_pattern)); @@ -226,7 +227,8 @@ session_from_server_sync_item(options & client_voice, info.client.unparsed(), server)); shared_ptr - wrapped(new netsync_session(opts, lua, project, + wrapped(new netsync_session(sess.get(), + opts, lua, project, keys, role, info.client.include_pattern, info.client.exclude_pattern, ============================================================ --- network/netsync_session.cc d29ead19e030ce5d2f3d9072f4302ad691b0e967 +++ network/netsync_session.cc 3c16b8a8db73617c18ce23ddad491afceb64fdd8 @@ -67,7 +67,8 @@ write_pubkey(key_name const & id, insert_variable_length_string(pub(), out); } -netsync_session::netsync_session(options & opts, +netsync_session::netsync_session(session * owner, + options & opts, lua_hooks & lua, project_t & project, key_store & keys, @@ -75,6 +76,7 @@ netsync_session::netsync_session(options globish const & our_include_pattern, globish const & our_exclude_pattern, bool initiated_by_server) : + wrapped_session(owner), role(role), our_include_pattern(our_include_pattern), our_exclude_pattern(our_exclude_pattern), @@ -82,15 +84,6 @@ netsync_session::netsync_session(options project(project), keys(keys), lua(lua), - use_transport_auth(opts.use_transport_auth), - signing_key(keys.signing_key), - received_remote_key(false), - session_key(constants::netsync_key_initializer), - read_hmac(netsync_session_key(constants::netsync_key_initializer), - use_transport_auth), - write_hmac(netsync_session_key(constants::netsync_key_initializer), - use_transport_auth), - authenticated(false), byte_in_ticker(NULL), byte_out_ticker(NULL), cert_in_ticker(NULL), @@ -101,7 +94,6 @@ netsync_session::netsync_session(options certs_in(0), certs_out(0), revs_in(0), revs_out(0), keys_in(0), keys_out(0), - saved_nonce(""), set_totals(false), epoch_refiner(epoch_item, get_voice(), *this), key_refiner(key_item, get_voice(), *this), @@ -131,6 +123,7 @@ void netsync_session::on_end(size_t iden void netsync_session::on_end(size_t ident) { + int error_code = get_error_code(); if (shutdown_confirmed()) error_code = error_codes::no_error; else if (error_code == error_codes::no_transfer && @@ -614,19 +607,6 @@ void } void -netsync_session::queue_hello_cmd(key_name const & key_name, - rsa_pub_key const & pub, - id const & nonce) -{ - netcmd cmd(get_version()); - if (use_transport_auth) - cmd.write_hello_cmd(key_name, pub, nonce); - else - cmd.write_hello_cmd(key_name, rsa_pub_key(), nonce); - write_netcmd(cmd); -} - -void netsync_session::request_service() { @@ -649,14 +629,6 @@ void } void -netsync_session::queue_confirm_cmd() -{ - netcmd cmd(get_version()); - cmd.write_confirm_cmd(); - write_netcmd(cmd); -} - -void netsync_session::queue_refine_cmd(refinement_type ty, merkle_node const & node) { string typestr; @@ -1140,7 +1112,7 @@ netsync_session::dispatch_payload(netcmd switch (cmd.get_cmd_code()) { case refine_cmd: - require(authenticated, "refine netcmd received when authenticated"); + require(get_authenticated(), "refine netcmd received when authenticated"); { merkle_node node; refinement_type ty; @@ -1150,7 +1122,7 @@ netsync_session::dispatch_payload(netcmd break; case done_cmd: - require(authenticated, "done netcmd received when not authenticated"); + require(get_authenticated(), "done netcmd received when not authenticated"); { size_t n_items; netcmd_item_type type; @@ -1160,7 +1132,7 @@ netsync_session::dispatch_payload(netcmd break; case data_cmd: - require(authenticated, "data netcmd received when not authenticated"); + require(get_authenticated(), "data netcmd received when not authenticated"); require(role == sink_role || role == source_and_sink_role, "data netcmd received in source or source/sink role"); @@ -1174,7 +1146,7 @@ netsync_session::dispatch_payload(netcmd break; case delta_cmd: - require(authenticated, "delta netcmd received when not authenticated"); + require(get_authenticated(), "delta netcmd received when not authenticated"); require(role == sink_role || role == source_and_sink_role, "delta netcmd received in source or source/sink role"); @@ -1218,6 +1190,81 @@ netsync_session::maybe_step() } } +void +netsync_session::prepare_to_confirm(key_identity_info const & client_identity, + bool use_transport_auth) +{ + if (!get_authenticated() && role != source_role && use_transport_auth) + { + error(error_codes::not_permitted, + F("rejected attempt at anonymous connection for write").str()); + } + + set ok_branches, all_branches; + + project.get_branch_list(all_branches); + globish_matcher matcher(our_include_pattern, our_exclude_pattern); + + for (set::const_iterator i = all_branches.begin(); + i != all_branches.end(); i++) + { + if (matcher((*i)())) + { + if (use_transport_auth) + { + if (!get_authenticated()) + { + if (!lua.hook_get_netsync_read_permitted((*i)())) + error(error_codes::not_permitted, + (F("anonymous access to branch '%s' denied by server") + % *i).str()); + } + else + { + if (!lua.hook_get_netsync_read_permitted((*i)(), client_identity)) + error(error_codes::not_permitted, + (F("denied '%s' read permission for '%s' excluding '%s' because of branch '%s'") + % client_identity.id + % our_include_pattern % our_exclude_pattern % *i).str()); + } + } + ok_branches.insert(*i); + } + } + + if (get_authenticated()) + { + P(F("allowed '%s' read permission for '%s' excluding '%s'") + % client_identity.id % our_include_pattern % our_exclude_pattern); + } + else if (use_transport_auth) + { + P(F("allowed anonymous read permission for '%s' excluding '%s'") + % our_include_pattern % our_exclude_pattern); + } + else + { + P(F("allowed anonymous read/write permission for '%s' excluding '%s'") + % our_include_pattern % our_exclude_pattern); + } + + if (use_transport_auth && (role == sink_role || role == source_and_sink_role)) + { + if (!lua.hook_get_netsync_write_permitted(client_identity)) + { + error(error_codes::not_permitted, + (F("denied '%s' write permission for '%s' excluding '%s'") + % client_identity.id + % our_include_pattern % our_exclude_pattern).str()); + } + + P(F("allowed '%s' write permission for '%s' excluding '%s'") + % client_identity.id % our_include_pattern % our_exclude_pattern); + } + + rebuild_merkle_trees(ok_branches); +} + bool netsync_session::process(transaction_guard & guard, netcmd const & cmd_in) { @@ -1393,6 +1440,7 @@ netsync_session::rebuild_merkle_trees(se W(F("Cannot find key '%s'") % *key); } inserted_keys.insert(*key); + L(FL("including key %s by special request") % *key); } } ============================================================ --- network/netsync_session.hh e848afaf9518a827735efc982ebe5ca6f3ed1d57 +++ network/netsync_session.hh 5d914d855e5f2b486876db5b997d8c65e8751cd3 @@ -40,17 +40,8 @@ netsync_session: project_t & project; key_store & keys; lua_hooks & lua; - bool use_transport_auth; - key_id const & signing_key; std::vector keys_to_push; - bool received_remote_key; - key_id remote_peer_key_id; - netsync_session_key session_key; - chained_hmac read_hmac; - chained_hmac write_hmac; - bool authenticated; - std::auto_ptr byte_in_ticker; std::auto_ptr byte_out_ticker; std::auto_ptr cert_in_ticker; @@ -72,10 +63,6 @@ netsync_session: std::vector sent_keys; std::vector sent_certs; - id saved_nonce; - - int error_code; - mutable bool set_totals; // Interface to refinement. @@ -98,7 +85,8 @@ public: void note_cert(id const & c); public: - netsync_session(options & opts, + netsync_session(session * owner, + options & opts, lua_hooks & lua, project_t & project, key_store & keys, @@ -113,6 +101,8 @@ public: bool have_work() const; void accept_service(); void request_service(); + void prepare_to_confirm(key_identity_info const & remote_key, + bool use_transport_auth); void on_begin(size_t ident, key_identity_info const & remote_key); void on_end(size_t ident); @@ -138,10 +128,6 @@ private: // Outgoing queue-writers. void queue_done_cmd(netcmd_item_type type, size_t n_items); - void queue_hello_cmd(key_name const & key_name, - rsa_pub_key const & pub_encoded, - id const & nonce); - void queue_confirm_cmd(); void queue_refine_cmd(refinement_type ty, merkle_node const & node); void queue_data_cmd(netcmd_item_type type, id const & item, @@ -156,15 +142,6 @@ private: key_name const & server_keyname, rsa_pub_key const & server_key, id const & nonce); - bool process_anonymous_cmd(protocol_role role, - globish const & their_include_pattern, - globish const & their_exclude_pattern); - bool process_auth_cmd(protocol_role role, - globish const & their_include_pattern, - globish const & their_exclude_pattern, - key_id const & client, - id const & nonce1, - rsa_sha1_signature const & signature); bool process_refine_cmd(refinement_type ty, merkle_node const & node); bool process_done_cmd(netcmd_item_type type, size_t n_items); bool process_data_cmd(netcmd_item_type type, ============================================================ --- network/reactor.cc 706efdfe2fec0191b90c598fbbc8c1d661bb98c0 +++ network/reactor.cc fa961bc15a1d0a1a6df66d04b2a57ca63941af34 @@ -25,9 +25,9 @@ void reactor::ready_for_io(shared_ptr item, transaction_guard & guard) { - if (item->do_work(guard)) + try { - try + if (item->do_work(guard)) { if (item->arm()) { @@ -43,24 +43,24 @@ void reactor::ready_for_io(shared_ptrcan_timeout()) can_have_timeout = true; } - catch (bad_decode & bd) + else { - W(F("protocol error while processing peer %s: '%s'") - % item->name() % bd.what); remove(item); } - catch (recoverable_failure & rf) - { - W(F("recoverable '%s' error while processing peer %s: '%s'") - % origin::type_to_string(rf.caused_by()) - % item->name() % rf.what()); - remove(item); - } } - else + catch (bad_decode & bd) { + W(F("protocol error while processing peer %s: '%s'") + % item->name() % bd.what); remove(item); } + catch (recoverable_failure & rf) + { + W(F("recoverable '%s' error while processing peer %s: '%s'") + % origin::type_to_string(rf.caused_by()) + % item->name() % rf.what()); + remove(item); + } } reactor::reactor() : have_pipe(false), ============================================================ --- network/session.cc a462c9e3e503442b765ca70488c1c1736215b931 +++ network/session.cc 822feddec150c3f60ea3ceee58a1eb0557a22964 @@ -36,7 +36,7 @@ session::session(options & opts, lua_hoo shared_ptr sock, bool use_transport_auth) : session_base(voice, peer, sock), - version(0), + version(opts.max_netsync_version), max_version(opts.max_netsync_version), min_version(opts.min_netsync_version), use_transport_auth(use_transport_auth), @@ -120,6 +120,7 @@ bool session::arm() if (cmd_in.read(min_version, max_version, inbuf, read_hmac)) { + L(FL("armed with netcmd having code '%d'") % cmd_in.get_cmd_code()); armed = true; } } @@ -135,7 +136,7 @@ bool session::do_work(transaction_guard bool session::do_work(transaction_guard & guard) { - bool armed = arm(); + arm(); bool is_goodbye = armed && cmd_in.get_cmd_code() == bye_cmd; bool is_error = armed && cmd_in.get_cmd_code() == error_cmd; if (completed_hello && !is_goodbye && !is_error) @@ -146,7 +147,14 @@ bool session::do_work(transaction_guard return true; else { + if (armed) + L(FL("doing work for peer '%s' with '%d' netcmd") + % get_peer() % cmd_in.get_cmd_code()); + else + L(FL("doing work for peer '%s' with no netcmd") + % get_peer()); bool ok = wrapped->do_work(guard, armed ? &cmd_in : 0); + armed = false; if (ok) { if (voice == client_voice @@ -177,6 +185,7 @@ bool session::do_work(transaction_guard { if (!armed) return true; + armed = false; switch (cmd_in.get_cmd_code()) { case usher_cmd: @@ -608,20 +617,31 @@ bool session::handle_service_request() switch (is_what) { case is_netsync: - wrapped.reset(new netsync_session(opts, + wrapped.reset(new netsync_session(this, + opts, lua, project, keys, corresponding_role(role), - globish(), - globish())); - wrapped->set_owner(this); + their_include, + their_exclude)); break; case is_automate: break; } - // queue_confirm_cmd(); + key_identity_info client_identity; + client_identity.id = client_id; + if (client_identity.id.inner()().empty()) + project.complete_key_identity(keys, lua, client_identity); + + wrapped->prepare_to_confirm(client_identity, use_transport_auth); + + netcmd cmd(get_version()); + cmd.write_confirm_cmd(); + write_netcmd(cmd); + + completed_hello = true; return true; } @@ -633,9 +653,11 @@ void session::write_netcmd(netcmd const string buf; cmd.write(buf, write_hmac); queue_output(buf); + L(FL("queued outgoing netcmd of type '%d'") % cmd.get_cmd_code()); } else - L(FL("dropping outgoing netcmd (because we're in error unwind mode)")); + L(FL("dropping outgoing netcmd of type '%d' (because we're in error unwind mode)") + % cmd.get_cmd_code()); } u8 session::get_version() const @@ -653,6 +675,16 @@ string session::get_peer() const return peer; } +int session::get_error_code() const +{ + return error_code; +} + +bool session::get_authenticated() const +{ + return authenticated; +} + void session::error(int errcode, string const & errmsg) { ============================================================ --- network/session.hh 4c73ddc1f08b1609a8150e6831664bb52efca02f +++ network/session.hh 1bf5b381aed995a946253357f8850523ce288021 @@ -83,6 +83,8 @@ public: u8 get_version() const; protocol_voice get_voice() const; std::string get_peer() const; + int get_error_code() const; + bool get_authenticated() const; void request_netsync(protocol_role role, globish const & our_include_pattern, ============================================================ --- network/wrapped_session.cc 4441e6888f140109a33da720a6424b460d51e95d +++ network/wrapped_session.cc fc865eb889c81d81330a98726cc3e72f1002297b @@ -14,10 +14,6 @@ using std::string; using std::string; -wrapped_session::wrapped_session() : - owner(0) -{ } - wrapped_session::wrapped_session(session * owner) : owner(owner) { } @@ -53,6 +49,16 @@ bool wrapped_session::encountered_error( return owner->encountered_error; } +int wrapped_session::get_error_code() const +{ + return owner->get_error_code(); +} + +bool wrapped_session::get_authenticated() const +{ + return owner->get_authenticated(); +} + string wrapped_session::get_peer() const { return owner->get_peer(); ============================================================ --- network/wrapped_session.hh a280328f066580ee9cd81d5d2a194d6bc7e691da +++ network/wrapped_session.hh 4110bd6a10485e7114abf283f968efcd27c4037a @@ -37,13 +37,14 @@ protected: bool output_overfull() const; bool encountered_error() const; bool shutdown_confirmed() const; + int get_error_code() const; + bool get_authenticated() const; void request_netsync(protocol_role role, globish const & include, globish const & exclude); void request_automate(); public: - wrapped_session(); explicit wrapped_session(session * owner); void set_owner(session * owner); @@ -56,6 +57,8 @@ public: virtual void accept_service() = 0; virtual std::string usher_reply_data() const = 0; virtual bool finished_working() const = 0; + virtual void prepare_to_confirm(key_identity_info const & remote_key, + bool use_transport_auth) = 0; virtual void on_begin(size_t ident, key_identity_info const & remote_key); virtual void on_end(size_t ident);