# # # patch "ChangeLog" # from [5e7be0ecfa379320d569de711c255345b07a74a7] # to [a7d6d3a553ba406d13b20f6e11d251ca4158a339] # # patch "constants.cc" # from [aa685613113f5ba800e3c64cc209e93072f86e7b] # to [1acad26d75341d5f94d6e76e8403c5a64cd88aad] # # patch "constants.hh" # from [ce01c73109bbe256a6ff1c75e6a3395e2b0e0b53] # to [27117e13cff08e2a15c9671a675b10d71c1c7369] # # patch "packet.cc" # from [5042d84abe71bbf3e1027a4475e51955370bef79] # to [c3846c546efaf5a006d8d208585997d1c2d53069] # ============================================================ --- ChangeLog 5e7be0ecfa379320d569de711c255345b07a74a7 +++ ChangeLog a7d6d3a553ba406d13b20f6e11d251ca4158a339 @@ -1,3 +1,12 @@ +2006-11-27 Zack Weinberg + + * packet.cc (feed_packet_consumer): Convert from functor object + into normal static function. Define all regular expression + objects statically, at file scope. Reorganize logic slightly. + (extract_packets, require): Adjust to match. + * constants.cc: Delete legal_packet_bytes and all regex_* constants. + * constants.hh: Similarly. + 2006-11-25 Zack Weinberg * pcrewrap.cc, pcrewrap.hh: New files. ============================================================ --- constants.cc aa685613113f5ba800e3c64cc209e93072f86e7b +++ constants.cc 1acad26d75341d5f94d6e76e8403c5a64cd88aad @@ -63,30 +63,14 @@ namespace constants // truncated. size_t const log_line_sz = 0x300; - // all the ASCII characters (bytes) which are legal in a packet. - char const * const legal_packet_bytes = - // LDH characters - "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "0123456789" - "-" - // extra base64 codes - "+/=" - // separators - "address@hidden" - // whitespace - " \r\n\t" - ; + // Note: If these change, the regular expressions in packet.cc may need to + // change too. - string const regex_legal_packet_bytes("([a-zA-Z0-9+/=[:space:]]+)"); - // all the ASCII characters (bytes) which are legal in a SHA1 hex id char const * const legal_id_bytes = "0123456789abcdef" ; - string const regex_legal_id_bytes("([[:xdigit:]]{40})"); - // all the ASCII characters (bytes) which are legal in an ACE string char const * const legal_ace_bytes = // LDH characters @@ -107,8 +91,6 @@ namespace constants "-" ; - string const regex_legal_cert_name_bytes("([-a-zA-Z0-9]+)"); - // all the ASCII characters (bytes) which can occur in key names char const * const legal_key_name_bytes = // LDH characters @@ -123,8 +105,6 @@ namespace constants ".@" ; - string const regex_legal_key_name_bytes("(address@hidden)"); - // merkle tree / netcmd / netsync related stuff size_t const merkle_fanout_bits = 4; ============================================================ --- constants.hh ce01c73109bbe256a6ff1c75e6a3395e2b0e0b53 +++ constants.hh 27117e13cff08e2a15c9671a675b10d71c1c7369 @@ -68,33 +68,18 @@ namespace constants // assumed width of the terminal, when we can't query for it directly extern size_t const default_terminal_width; - // all the ASCII characters (bytes) which are legal in a packet - extern char const * const legal_packet_bytes; - - // boost regex that matches the bytes in legal_packet_bytes - extern std::string const regex_legal_packet_bytes; - // all the ASCII characters (bytes) which are legal in an ACE string extern char const * const legal_ace_bytes; // all the ASCII characters (bytes) which are legal in a SHA1 hex id extern char const * const legal_id_bytes; - // boost regex that matches the bytes in legal_id_bytes - extern std::string const regex_legal_id_bytes; - // all the ASCII characters (bytes) which can occur in cert names extern char const * const legal_cert_name_bytes; - // boost regex that matches the bytes in legal_cert_name_bytes - extern std::string const regex_legal_cert_name_bytes; - // all the ASCII characters (bytes) which can occur in key names extern char const * const legal_key_name_bytes; - // boost regex that matches the bytes in legal_key_name_bytes - extern std::string const regex_legal_key_name_bytes; - // remaining constants are related to netsync protocol // number of bytes in the hash used in netsync ============================================================ --- packet.cc 5042d84abe71bbf3e1027a4475e51955370bef79 +++ packet.cc c3846c546efaf5a006d8d208585997d1c2d53069 @@ -322,133 +322,136 @@ packet_writer::consume_key_pair(rsa_keyp // -- remainder just deals with the regexes for reading packets off streams +// +// Note: If these change, the character sets in constants.cc may need to +// change too. -struct -feed_packet_consumer +static pcre::regex identr("\\A[[:xdigit:]]{40}\\Z"); +static pcre::regex keyr("address@hidden"); +static pcre::regex base64r("\\A[a-zA-Z0-9+/=[:space:]]+\\Z"); + +static pcre::regex fdelta_hdr("\\A([[:xdigit:]]{40})" // ident + "[[:space:]]+" + "([[:xdigit:]]{40})\\Z"); // ident + +static pcre::regex rcert_hdr("\\A([[:xdigit:]]{40})" // ident + "[[:space:]]+" + "([-a-zA-Z0-9]+)" // certname + "[[:space:]]+" + "(address@hidden)" // key + "[[:space:]]+" + "([a-zA-Z0-9+/=[:space:]]+)\\Z"); // base64 + +static pcre::regex keypair_body("\\A([a-zA-Z0-9+/=[:space:]]+)" // base64 + "#" + "([a-zA-Z0-9+/=[:space:]]+)\\Z"); // base64 + +inline void require(bool x) { - app_state & app; - packet_consumer & cons; - string ident; - string key; - string certname; - string base; - string sp; - feed_packet_consumer(packet_consumer & c, app_state & app_) - : app(app_), cons(c), - ident(constants::regex_legal_id_bytes), - key(constants::regex_legal_key_name_bytes), - certname(constants::regex_legal_cert_name_bytes), - base(constants::regex_legal_packet_bytes), - sp("[[:space:]]+") - {} - void require(bool x) const - { - E(x, F("malformed packet")); - } - void operator()(pcre::matches &res) const - { - if (res.size() != 4) - throw oops("matched impossible packet with " - + lexical_cast(res.size()) + " matching parts: " + - string(res[0].first, res[0].second)); - I(res[1].matched()); - I(res[2].matched()); - I(res[3].matched()); - string type(res[1].first, res[1].second); - string args(res[2].first, res[2].second); - string body(res[3].first, res[3].second); - if (pcre::regex("[fr]data").match(type)) - { - L(FL("read data packet")); - require(pcre::regex(ident).match(args)); - require(pcre::regex(base).match(body)); - base64 > body_packed(trim_ws(body)); - data contents; - unpack(body_packed, contents); - if (type == "rdata") - cons.consume_revision_data(revision_id(hexenc(args)), - revision_data(contents)); - else if (type == "fdata") - cons.consume_file_data(file_id(hexenc(args)), - file_data(contents)); - else - throw oops("matched impossible data packet with head '" + type + "'"); - } - else if (type == "fdelta") - { - L(FL("read delta packet")); - pcre::matches matches; - require(pcre::regex(ident + sp + ident).match(args, matches)); - string src_id(matches[1].str()); - string dst_id(matches[2].str()); - require(pcre::regex(base).match(body)); - base64 > body_packed(trim_ws(body)); - delta contents; - unpack(body_packed, contents); - cons.consume_file_delta(file_id(hexenc(src_id)), - file_id(hexenc(dst_id)), - file_delta(contents)); - } - else if (type == "rcert") - { - L(FL("read cert packet")); - pcre::matches matches; - require(pcre::regex(ident + sp + certname + sp + key + sp + base) - .match(args, matches)); - string certid(matches[1].str()); - string name(matches[2].str()); - string keyid(matches[3].str()); - string val(matches[4].str()); - string contents(trim_ws(body)); + E(x, F("malformed packet")); +} - // canonicalize the base64 encodings to permit searches - cert t = cert(hexenc(certid), - cert_name(name), - base64(canonical_base64(val)), - rsa_keypair_id(keyid), - base64(canonical_base64(contents))); - cons.consume_revision_cert(revision(t)); - } - else if (type == "pubkey") - { - L(FL("read pubkey data packet")); - require(pcre::regex(key).match(args)); - require(pcre::regex(base).match(body)); - string contents(trim_ws(body)); - cons.consume_public_key(rsa_keypair_id(args), - base64(contents)); - } - else if (type == "keypair") - { - L(FL("read keypair data packet")); - require(pcre::regex(key).match(args)); +static void feed_packet_consumer(pcre::matches & res, + packet_consumer & cons, + app_state & app) +{ + if (res.size() != 4) + throw oops("matched impossible packet with " + + lexical_cast(res.size()) + " matching parts: " + + string(res[0].first, res[0].second)); + I(res[1].matched()); + I(res[2].matched()); + I(res[3].matched()); + string type(res[1].first, res[1].second); + string args(res[2].first, res[2].second); + string body(res[3].first, res[3].second); + if ((type[0] == 'f' || type[0] == 'r') + && type.compare(1, type.size()-1, "data") == 0) + { + L(FL("read data packet")); + require(identr.match(args)); + require(base64r.match(body)); + base64 > body_packed(trim_ws(body)); + data contents; + unpack(body_packed, contents); + if (type == "rdata") + cons.consume_revision_data(revision_id(hexenc(args)), + revision_data(contents)); + else if (type == "fdata") + cons.consume_file_data(file_id(hexenc(args)), + file_data(contents)); + else + throw oops("matched impossible data packet with head '" + type + "'"); + } + else if (type == "fdelta") + { + L(FL("read delta packet")); + pcre::matches matches; + require(fdelta_hdr.match(args, matches)); + require(base64r.match(body)); + file_id src_id(hexenc(matches[1].str())); + file_id dst_id(hexenc(matches[2].str())); - pcre::matches matches; - require(pcre::regex(base + "#" + base).match(body, matches)); - string pub_dat(trim_ws(matches[1].str())); - string priv_dat(trim_ws(matches[2].str())); - cons.consume_key_pair(rsa_keypair_id(args), keypair(pub_dat, priv_dat)); - } - else if (type == "privkey") - { - L(FL("read pubkey data packet")); - require(pcre::regex(key).match(args)); - require(pcre::regex(base).match(body)); - string contents(trim_ws(body)); - keypair kp; - migrate_private_key(app, - rsa_keypair_id(args), - base64 >(contents), - kp); - cons.consume_key_pair(rsa_keypair_id(args), kp); - } - else - { - W(F("unknown packet type: '%s'") % type); - } - } -}; + base64 > body_packed(trim_ws(body)); + delta contents; + unpack(body_packed, contents); + cons.consume_file_delta(src_id, dst_id, file_delta(contents)); + } + else if (type == "rcert") + { + L(FL("read cert packet")); + pcre::matches matches; + require(rcert_hdr.match(args, matches)); + require(base64r.match(body)); + // canonicalize the base64 encodings to permit searches + hexenc certid(matches[1].str()); + cert_name name(matches[2].str()); + rsa_keypair_id keyid(matches[3].str()); + base64 val(canonical_base64(matches[4].str())); + base64 contents(canonical_base64(trim_ws(body))); + + cert t(certid, name, val, keyid, contents); + cons.consume_revision_cert(revision(t)); + } + else if (type == "pubkey") + { + L(FL("read pubkey data packet")); + require(keyr.match(args)); + require(base64r.match(body)); + + base64 contents(trim_ws(body)); + cons.consume_public_key(rsa_keypair_id(args), contents); + } + else if (type == "keypair") + { + L(FL("read keypair data packet")); + pcre::matches matches; + require(keyr.match(args)); + require(keypair_body.match(body, matches)); + + string pub_dat(trim_ws(matches[1].str())); + string priv_dat(trim_ws(matches[2].str())); + cons.consume_key_pair(rsa_keypair_id(args), keypair(pub_dat, priv_dat)); + } + else if (type == "privkey") + { + L(FL("read privkey data packet")); + require(keyr.match(args)); + require(base64r.match(body)); + + rsa_keypair_id keyid(args); + base64 > contents (trim_ws(body)); + keypair kp; + migrate_private_key(app, keyid, contents, kp); + cons.consume_key_pair(keyid, kp); + } + else + { + W(F("unknown packet type: '%s'") % type); + } +} + static size_t extract_packets(string const & s, packet_consumer & cons, app_state & app) { @@ -457,11 +460,10 @@ extract_packets(string const & s, packet "\\[end\\]"); size_t count = 0; pcre::matches m; - feed_packet_consumer fcons(cons, app); while (expr.nextmatch(s, m)) { - fcons(m); + feed_packet_consumer(m, cons, app); count++; } return count;