# # # add_file "do-fuzz.sh" # content [4b9493f21812343bf64c7553516d3959d605ea4d] # # patch "netcmd.cc" # from [64d6c56e6b3de68bd2e3cf34c3530b5fb14b54d5] # to [4acc7331c4661ecda356cc1693c996a12d1932b2] # # patch "netsync.cc" # from [126ff0ef642b515981807cd45f0799f9e121333d] # to [ce757a0ff0e6c6283603ec514e2bf136c80b4783] # # set "do-fuzz.sh" # attr "mtn:execute" # value "true" # ============================================================ --- do-fuzz.sh 4b9493f21812343bf64c7553516d3959d605ea4d +++ do-fuzz.sh 4b9493f21812343bf64c7553516d3959d605ea4d @@ -0,0 +1,88 @@ +#!/bin/bash + +mkdir -p do-fuzz.d +cd do-fuzz.d + +rm -rf * +mkdir keys + +cat >rcfile </dev/null + mtn add $FILE --quiet + mtn ci -m "This is a random $RANDOM commit message." --quiet $KEYOPTS --root . + ~/src/nvm-fuzzy-networking/build/mtn sy localhost:12345 \* \ + --ticker none $KEYOPTS $PUSHKEY +} +client() { + CLI_COUNT=0 + while true + do + client_iter + CLI_COUNT=$(expr $CLI_COUNT + 1) + echo "Tried $CLI_COUNT connections so far" + done +} +watchdog() { + while sleep 2 + do + X=$(ps -Af | grep -E 'pts/7.*m[t]n sy' | awk '{print $2};') + sleep 5 + test "$X" -a -d /proc/$X && kill $X + done +} + +serve & +client & +#watchdog & + +do_kill() { + PGID=$(echo $(ps -o pgid $$ | tail -n1)) + echo "PGID is $PGID" + echo "Killing '/bin/kill INT -$PGID'" + /bin/kill INT -$PGID + sleep 2 +} + +trap do_kill int + +wait + ============================================================ --- netcmd.cc 64d6c56e6b3de68bd2e3cf34c3530b5fb14b54d5 +++ netcmd.cc 4acc7331c4661ecda356cc1693c996a12d1932b2 @@ -20,6 +20,9 @@ #include "hmac.hh" #include "globish.hh" +#include "key_store.hh" +Botan::RandomNumberGenerator * fuzzy_rng = 0; + using std::string; static netcmd_item_type @@ -65,6 +68,29 @@ netcmd::operator==(netcmd const & other) payload == other.payload; } +double +rnd() +{ + if (!fuzzy_rng) + return 0; + uint32_t x; + fuzzy_rng->randomize((Botan::byte*)&x, 4); + return (double(x) / uint32_t(-1)); +} +bool +maybe(double p) +{ + return rnd() < p; +} +int +pick(int n) +{ + return rnd() * n; +} + +double p_fuzz_packet = 0.01; +double p_bad_hmac = 0.0001; + // note: usher_reply_cmd does not get included in the hmac. void netcmd::write(string & out, chained_hmac & hmac) const @@ -72,12 +98,34 @@ netcmd::write(string & out, chained_hmac size_t oldlen = out.size(); out += static_cast(version); out += static_cast(cmd_code); + + // maybe mess up the data + // don't mess up refine commands very often, that drops the + // connection before we get to mess up anything else + if (maybe(p_fuzz_packet) && (cmd_code != refine_cmd || maybe(p_fuzz_packet / 10))) + { + int pos = pick(payload.size()); + fuzzy_rng->randomize((Botan::byte*)&payload[pos], 1); + P(F("fuzzy payload!")); + } + + // Don't mess up the packet length. That will have the same effect as + // messing up the hmac, except that it might cause a big delay while the + // server waits for more input. The timeout for this is annoyingly long, + // and would slow testing by absurd amounts. insert_variable_length_string(payload, out); if (hmac.is_active() && cmd_code != usher_reply_cmd) { string digest = hmac.process(out, oldlen); I(hmac.hmac_length == constants::netsync_hmac_value_length_in_bytes); + // or maybe mess up the hmac + if (maybe(p_bad_hmac)) + { + int pos = pick(digest.size()); + fuzzy_rng->randomize((Botan::byte*)&digest[pos], 1); + P(F("fuzzy hmac!")); + } out.append(digest); } } ============================================================ --- netsync.cc 126ff0ef642b515981807cd45f0799f9e121333d +++ netsync.cc ce757a0ff0e6c6283603ec514e2bf136c80b4783 @@ -62,6 +62,8 @@ #include "netxx/streamserver.h" #include "netxx/timeout.h" #include "netxx_pipe.hh" + +extern Botan::RandomNumberGenerator * fuzzy_rng; // TODO: things to do that will break protocol compatibility // -- need some way to upgrade anonymous to keyed pull, without user having // to explicitly specify which they want @@ -886,7 +888,10 @@ session::session(options & opts, rev_refiner(revision_item, voice, *this), rev_enumerator(project, *this), initiated_by_server(initiated_by_server) -{} +{ + if (fuzzy_rng == 0) + fuzzy_rng = &keys.get_rng(); +} session::~session() {