diff -uNr a/blatta/README.txt b/blatta/README.txt --- a/blatta/README.txt 0a24e35c1f08fa449b1f6acc9a61b373aca19bf43fbb3a728c1fc89123b8a456d193cc8bf4eeb9bba90f18e7a82094f1b24bf10e20f6d0729367127d502d3fe7 +++ b/blatta/README.txt bc8aaa1f75e7830f0359f5a35958fc19b8bbdd316e7a97cf66bba38e0a616bd673751249ce6e9fa2aad7f05e32af3ae9b351e87cac8a679fb8d381510514d813 @@ -25,15 +25,8 @@ GETTING STARTED 1. Launch blatta with something like the following command: -./blatta --port=6668 --address-table-path config.py +./blatta --irc-port=6668 2. Add a peer using the peer command. 3. Use genkey to generate a key. 4. Add the key to the peer using the key command. 5. Add an address for the peer using the address command. - -NOTES FOR DIFF/PATCH N00B5 - -To apply the genesis patch (or any patch) to the current directory -and recreate the directory structure of the original: - -patch -p1 -ruN < /genesis.vdiff diff -uNr a/blatta/blatta b/blatta/blatta --- a/blatta/blatta 01f00ef74cd2143c7b07ea439284cea743c0406301e7d9255ed9287a022d8c2db04125a346caa2b1085e38bfd44d1fe342a52467c2511f6c714c79db9954f89d +++ b/blatta/blatta 78e7bff9012264c8334e1df4d0d03a3ef609ef39330f1a3809df3a8e3fb4ffc2c2e212f505cabb4a05df90174d39cf5f085d71ec3f6be1cd6745038bda5bdfc1 @@ -18,7 +18,7 @@ def main(argv): op = OptionParser( version=VERSION, - description="alcuin is a small and limited IRC server emulator for gossip networks.") + description="Blatta is an implementation of a Pest network station.") op.add_option( "-a", "--address-table-path", help="Import address table from specified file") @@ -50,18 +50,14 @@ metavar="X", help="display file X as message of the day") op.add_option( - "-s", "--ssl-pem-file", - metavar="FILE", - help="enable SSL and use FILE as the .pem certificate+key") - op.add_option( "-p", "--password", metavar="X", help="require connection password X; default: no password") op.add_option( - "--ports", + "--irc-ports", metavar="X", - help="listen to ports X (a list separated by comma or whitespace);" - " default: 6667 or 6697 if SSL is enabled") + help="listen on ports X for irc client connections (a list separated by comma or whitespace);" + " default: 6667") op.add_option( "--udp-port", metavar="X", @@ -90,17 +86,14 @@ (options, args) = op.parse_args(argv[1:]) if options.debug: options.verbose = True - if options.ports is None: - if options.ssl_pem_file is None: - options.ports = "6667" - else: - options.ports = "6697" + if options.irc_ports is None: + options.irc_ports = "6697" if options.udp_port is None: options.udp_port = 7778 else: options.udp_port = int(options.udp_port) if options.db_path is None: - options.db_path = "alcuin.db" + options.db_path = "blatta.db" if options.config_file_path is None: options.config_file_path = "config.py" if options.chroot: @@ -127,13 +120,13 @@ " startup. If you really intend to run as root, use" " \"--setuid root\".") - ports = [] - for port in re.split(r"[,\s]+", options.ports): + irc_ports = [] + for port in re.split(r"[,\s]+", options.irc_ports): try: - ports.append(int(port)) + irc_ports.append(int(port)) except ValueError: op.error("bad port: %r" % port) - options.ports = ports + options.irc_ports = irc_ports server = Server(options) if options.daemon: server.daemonize() diff -uNr a/blatta/lib/channel.py b/blatta/lib/channel.py --- a/blatta/lib/channel.py 29051fff4c05169a752059f5102291f981a73ec3c5112cb8135865919a2a8ce0f02db32c7c95639f39b51e2f444af5229febca7fe113d06b7d5c347c3f46bf30 +++ b/blatta/lib/channel.py 9e92e286e45f8d293df0ef2126dbcd90e95fd853434d94fa37e55705d2dc7517cf768acad7b54029a666926e2e489541ebbe618334600b8166ee8898fd01d094 @@ -1,3 +1,5 @@ +import os + class Channel(object): def __init__(self, server, name): self.server = server diff -uNr a/blatta/lib/client.py b/blatta/lib/client.py --- a/blatta/lib/client.py 622dc40643fd936b33df0f60bac3167453dd1684021504c1d7201e07aea2140b17c4d857cc106ddd6df9963a8003e84d938696796c5d2001de2b68dbe5533f23 +++ b/blatta/lib/client.py 39920c295fdaf1bb2b6a76564da9b8dc1770ba9fed4c145b72854432f302d919c9ea611485e0de01eb544eba1052471133c509ab8c4cc61c12e6c7ec83ea2b8d @@ -485,8 +485,11 @@ def peer_handler(): if len(arguments) == 1: - self.server.state.add_peer(arguments[0]) - self.pest_reply("added new peer %s" % arguments[0]) + try: + self.server.state.add_peer(arguments[0]) + self.pest_reply("added new peer %s" % arguments[0]) + except: + self.pest_reply("error attempting to add peer %s" % arguments[0]) else: self.pest_reply("Usage: PEER ") @@ -538,7 +541,8 @@ address_ip, port = string.split(address, ":") self.server.state.update_address_table({"handle": handle, "address": address_ip, - "port": port}) + "port": port}, + False) self.pest_reply("updated address table: %s %s" % (handle, address)) return elif len(arguments) > 2: @@ -548,7 +552,7 @@ for address in at: self.pest_reply("%s %s %s" % (address["handle"], address["address"], - address["updated_at"])) + address["active_at"])) else: self.pest_reply("no results") diff -uNr a/blatta/lib/infosec.py b/blatta/lib/infosec.py --- a/blatta/lib/infosec.py ae8fe58a8f92689212f3ccdb9a30a530cd19b0ce5ad7aeecdf5eee1c6c9505ae56df43a3132ca534d0bdb745d469cdbce7f2a51ef30900259dada9e894288827 +++ b/blatta/lib/infosec.py 0646687de5d54fd0278b8265786d9e5bb65492dc81f323249b57c129d5293cf605f384b13354379d970aaf04c1757866529320f2b0d8226f64a0f269398de6cb @@ -24,6 +24,10 @@ MESSAGE_PACKET_FORMAT = " %s" % packet_info) for peer in self.state.get_peers(): if peer.get_key() != None: message = self.infosec.unpack(peer, data) - if(message != None): - self.print_debug("valid message from peer: %s" % peer.handles[0]) + error_code = message["error_code"] + if(error_code == None): + self.print_debug("[%s] -> %s" % (peer.handles[0], message["body"])) # we only update the address table if the speaker is same as peer @@ -159,8 +169,8 @@ if idx != None: self.state.update_address_table({"handle": message["speaker"], - "address": address[0], - "port": address[1] + "address": address[0], + "port": address[1] }) # send the message to all clients for c in self.clients: @@ -171,7 +181,18 @@ if(message["command"] == BROADCAST) and message["bounces"] < MAX_BOUNCES: self.rebroadcast(peer, message) return - self.print_debug("Unknown peer: %s %d" % (address[0], address[1])) + elif error_code == STALE_PACKET: + self.print_debug("[%s:%d] -> stale packet: %s" % packet_info) + return + elif error_code == DUPLICATE_PACKET: + self.print_debug("[%s:%d] -> duplicate packet: %s" % packet_info) + return + elif error_code == MALFORMED_PACKET: + self.print_debug("[%s:%d] -> malformed packet: %s" % packet_info) + return + elif error_code == INVALID_SIGNATURE: + pass + self.print_debug("[%s:%d] -> martian packet: %s" % packet_info) def peer_message(self, message): message["original"] = True @@ -201,9 +222,10 @@ # Setup UDP first self.udp_server_socket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM) self.udp_server_socket.bind((self.address, self.udp_port)) + self.print_info("Listening for Pest packets on udp port %d." % self.udp_port) serversockets = [] - for port in self.ports: + for port in self.irc_ports: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) try: @@ -214,7 +236,7 @@ s.listen(5) serversockets.append(s) del s - self.print_info("Listening on port %d." % port) + self.print_info("Listening for IRC connections on port %d." % port) if self.chroot: os.chdir(self.chroot) os.chroot(self.chroot) @@ -232,7 +254,7 @@ [x.socket for x in self.clients.values() if x.write_queue_size() > 0], [], - 0) + 1) for x in inputready: if x == self.udp_server_socket: bytes_address_pair = self.udp_server_socket.recvfrom(PACKET_SIZE) @@ -242,19 +264,6 @@ self.clients[x].socket_readable_notification() else: (conn, addr) = x.accept() - if self.ssl_pem_file: - import ssl - try: - conn = ssl.wrap_socket( - conn, - server_side=True, - certfile=self.ssl_pem_file, - keyfile=self.ssl_pem_file) - except ssl.SSLError as e: - self.print_error( - "SSL error for connection from %s:%s: %s" % ( - addr[0], addr[1], e)) - continue self.clients[conn] = Client(self, conn) self.print_info("Accepted connection from %s:%s." % ( addr[0], addr[1])) diff -uNr a/blatta/lib/state.py b/blatta/lib/state.py --- a/blatta/lib/state.py 5e6216fb339f461e197c6c2f878148cbf2032ce6c433f83df2c29e88b31c467f9c8b689e14d5b0471a6275e7a40e286ac9dbea69c60d3a16171e4bae6b091339 +++ b/blatta/lib/state.py 7621f8a10842a06cbd590e6dc7460985c762458875771369d1707f24d6449021762a24277e9b1bbb017f5df601219c8b80a38e6142861503ec7dc265f013a92a @@ -13,6 +13,7 @@ self.cursor.execute("create table if not exists at(handle_id integer,\ address text not null,\ port integer not null,\ + active_at datetime default null,\ updated_at datetime default current_timestamp,\ unique(handle_id, address, port))") @@ -37,7 +38,7 @@ def get_at(self, handle=None): at = [] if handle == None: - results = self.cursor.execute("select handle_id,address,port,updated_at from at\ + results = self.cursor.execute("select handle_id,address,port,active_at from at\ order by updated_at desc").fetchall() else: result = self.cursor.execute("select handle_id from handles where handle=?", @@ -46,7 +47,7 @@ handle_id = result[0] else: return [] - results = self.cursor.execute("select handle_id,address,port,updated_at from at \ + results = self.cursor.execute("select handle_id,address,port,active_at from at \ where handle_id=? order by updated_at desc", (handle_id,)).fetchall() for result in results: @@ -55,7 +56,7 @@ (handle_id,)).fetchone()[0] at.append({"handle": h, "address": "%s:%s" % (address, port), - "updated_at": updated_at}) + "active_at": updated_at}) return at @@ -96,30 +97,33 @@ self.cursor.execute("insert into handles(peer_id, handle) values(?, ?)", (peer_id, peer["name"])) handle_id = self.cursor.lastrowid - self.cursor.execute("insert into at(handle_id, address, port) values(?, ?, ?)", - (handle_id, peer["address"], peer["port"])) + self.cursor.execute("insert into at(handle_id, address, port, updated_at) values(?, ?, ?, ?)", + (handle_id, peer["address"], peer["port"], None)) self.cursor.execute("insert into keys(peer_id, key) values(?, ?)", (peer_id, key)) self.conn.commit() - def update_address_table(self, peer): + def update_address_table(self, peer, set_active_at=True): row = self.cursor.execute("select handle_id from handles where handle=?", (peer["handle"],)).fetchone() if row != None: handle_id = row[0] else: return - + try: self.cursor.execute("insert into at(handle_id, address, port) values(?, ?, ?)", (handle_id, peer["address"], peer["port"])) - self.conn.commit() except sqlite3.IntegrityError as ex: self.cursor.execute("update at set updated_at = current_timestamp\ where handle_id=? and address=? and port=?", (handle_id, peer["address"], peer["port"])) - self.conn.commit() + if set_active_at: + self.cursor.execute("update at set active_at = current_timestamp\ + where handle_id=? and address=? and port=?", + (handle_id, peer["address"], peer["port"])) + self.conn.commit() def add_peer(self, handle): self.cursor.execute("insert into wot(peer_id) values(null)") @@ -127,6 +131,7 @@ self.cursor.execute("insert into handles(peer_id, handle) values(?, ?)", (peer_id, handle)) self.conn.commit() + def remove_peer(self, handle): # get peer id diff -uNr a/blatta/start_test_net.sh b/blatta/start_test_net.sh --- a/blatta/start_test_net.sh 158ee3120edaf743c2990baddea12d89e0626521ba45034b0c92cd182d75cea88f19758460c4758439ed866f902749b3217333613ec1f4668e9257a95c71c138 +++ b/blatta/start_test_net.sh 5256691880aa5d35f8534834ad318afefb85fe95b62e9ad41fe83c7dce5d1e4bf4b1727b153492199c3567a77e65a4c36fb644af046c74c0523511e263353d96 @@ -1,6 +1,6 @@ #!/bin/bash # start 3 servers on different ports -./blatta --debug --port 6668 --udp-port 7778 --db-path a.db --address-table-path test_net_configs/a.py > logs/a & -./blatta --debug --port 6669 --udp-port 7779 --db-path b.db --address-table-path test_net_configs/b.py > logs/b & -./blatta --debug --port 6670 --udp-port 7780 --db-path c.db --address-table-path test_net_configs/c.py > logs/c & +./blatta --debug --irc-port 6668 --udp-port 7778 --db-path a.db --address-table-path test_net_configs/a.py > logs/a & +./blatta --debug --irc-port 6669 --udp-port 7779 --db-path b.db --address-table-path test_net_configs/b.py > logs/b & +./blatta --debug --irc-port 6670 --udp-port 7780 --db-path c.db --address-table-path test_net_configs/c.py > logs/c &