# # patch "ChangeLog" # from [7c81492d87920b0ba7c60928c77b74902776a9cd] # to [d816eaad5f1f762d0611791411a21e7a0a14b90a] # # patch "netsync.cc" # from [e9786aaaad7990675f952101b544f35fd168df4c] # to [cebe0aa43271d815df89c6012d070881c4f589a6] # --- ChangeLog +++ ChangeLog @@ -1,5 +1,13 @@ 2005-07-07 Nathaniel Smith + * netsync.cc (process_hello_cmd, process_anonymous_cmd) + (process_auth_cmd): Change permission checking -- always build + merkle tree (even when a pure sink), send permission denied and + abort whenever client tries to read/write a branch they don't have + access to. + +2005-07-07 Nathaniel Smith + * ChangeLog: fixup formatting. 2005-07-06 Matt Johnston --- netsync.cc +++ netsync.cc @@ -124,17 +124,6 @@ // bytes of 0 during authentication, and a 20-byte random key chosen // by the client after authentication (discussed below). // -//---- Pre-v5 packet format ---- -// -// the protocol is a simple binary command-packet system over tcp; each -// packet consists of a byte which identifies the protocol version, a byte -// which identifies the command name inside that version, a size_t sent as -// a uleb128 indicating the length of the packet, and then that many bytes -// of payload, and finally 4 bytes of adler32 checksum (in LSB order) over -// the payload. -// -// ---- end pre-v5 packet format ---- -// // decoding involves simply buffering until a sufficient number of bytes are // received, then advancing the buffer pointer. any time an integrity check // (the HMAC) fails, the protocol is assumed to have lost synchronization, and @@ -1763,6 +1752,8 @@ this->remote_peer_key_hash = their_key_hash_decoded; } + // clients always include in the synchronization set, every branch that the + // user requested vector branchnames; set ok_branches; get_branches(app, branchnames); @@ -1770,7 +1761,7 @@ i != branchnames.end(); i++) { if (our_matcher(*i)) - ok_branches.insert(utf8(*i)); + ok_branches.insert(utf8(*i)); } rebuild_merkle_trees(app, ok_branches); @@ -1848,17 +1839,15 @@ for (vector::const_iterator i = branchnames.begin(); i != branchnames.end(); i++) { - if (our_matcher(*i) && their_matcher(*i) - && app.lua.hook_get_netsync_anonymous_read_permitted(*i)) - ok_branches.insert(utf8(*i)); + if (their_matcher(*i)) + if (our_matcher(*i) && app.lua.hook_get_netsync_anonymous_read_permitted(*i)) + ok_branches.insert(utf8(*i)); + else + { + error((F("anonymous access to branch '%s' denied by server") % *i).str()); + return true; + } } - if (ok_branches.empty()) - { - W(F("denied anonymous read permission for '%s' excluding '%s'\n") - % their_include_pattern % their_exclude_pattern); - this->saved_nonce = id(""); - return false; - } P(F("allowed anonymous read permission for '%s' excluding '%s'\n") % their_include_pattern % their_exclude_pattern); @@ -1934,27 +1923,29 @@ this->saved_nonce = id(""); return false; } + } - for (vector::const_iterator i = branchnames.begin(); - i != branchnames.end(); i++) + for (vector::const_iterator i = branchnames.begin(); + i != branchnames.end(); i++) + { + if (their_matcher(*i)) { - if (our_matcher(*i) && their_matcher(*i) - && app.lua.hook_get_netsync_read_permitted(*i, their_id)) + if (our_matcher(*i) && app.lua.hook_get_netsync_read_permitted(*i, their_id)) ok_branches.insert(utf8(*i)); + else + { + W(F("denied '%s' read permission for '%s' excluding '%s' because of branch '%s'\n") + % their_id % their_include_pattern % their_exclude_pattern % *i); + error((F("access to branch '%s' denied by server") % *i).str()); + return true; + } } - //if we're source_and_sink_role, continue even with no branches readable - //ex: serve --db=empty.db - if (ok_branches.empty() && their_role == sink_role) - { - W(F("denied '%s' read permission for '%s' excluding '%s'\n") - % their_id % their_include_pattern % their_exclude_pattern); - this->saved_nonce = id(""); - return false; - } + } - P(F("allowed '%s' read permission for '%s' excluding '%s'\n") - % their_id % their_include_pattern % their_exclude_pattern); - } + //if we're source_and_sink_role, continue even with no branches readable + //ex: serve --db=empty.db + P(F("allowed '%s' read permission for '%s' excluding '%s'\n") + % their_id % their_include_pattern % their_exclude_pattern); // client as source, server as sink (writing) @@ -1970,7 +1961,7 @@ if (!app.lua.hook_get_netsync_write_permitted(their_id)) { - W(F("denied '%s' write permission for '%s' excluding '%s' while running as pure source\n") + W(F("denied '%s' write permission for '%s' excluding '%s'\n") % their_id % their_include_pattern % their_exclude_pattern); this->saved_nonce = id(""); return false;