diff --git a/contrib/auto-naming/README b/contrib/auto-naming/README index df78491a79..e2f9ff8c2a 100644 --- a/contrib/auto-naming/README +++ b/contrib/auto-naming/README @@ -1,65 +1,6 @@ -=== AUTONAMING FOR TOR === - Tor directory authorities may maintain a binding of server identities -(their long term identity key) and nicknames. In their status documents -they may for each router they know tell if this is indeed the owner of -that nickname or not. +(their long term identity key) and nicknames. -This toolset allows automatic maintaining of a binding list of nicknames -to identity keys, implementing Tor proposal 123[1]. +The auto-naming scripts have been moved to svn in +projects/tor-naming/auto-naming/trunk/ -The rules are simple: - - A router claiming to be Bob becomes named (i.e. added to the binding list) - if there currently does not exist a different binding for that - nickname, the router has been around for a bit (2 weeks), and no other - router has used that nickname in a while (1 month). - - A binding is removed if the server that owns it has not been seen - in a long time (6 months). - - -=== REQUIREMENTS === - - * ruby, and its postgres DBI interface (Debian packages: ruby, ruby1.8, libdbi-ruby1.8, libdbd-pg-ruby1.8) - * postgres (tested with >= 8.1) - * cron - -=== SETUP === - - * copy this tree some place, like into a 'auto-naming' directory in your Tor's - data directory - * create a database and a user, modifying db-config.rb accordingly - * initialize the database by executing the sql statements in create-db.sql - * setup a cronjob that feeds the current consensus to the process-consensus - script regularly. - * once the database is sufficiently populated, maybe a month or so after the - previous step, setup a cronjob to regularly build the binding list using - the build-approved-routers script. You probably want to append a manually - managed list of rejections to that file and give it to tor as its - "approved-routers" file. - The Sample-Makefile and Sample-crontab demonstrate the method used at tor26. - - -1. https://tor-svn.freehaven.net/svn/tor/trunk/doc/spec/proposals/123-autonaming.txt - - - - -Copyright (c) 2007 Peter Palfrader - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/contrib/auto-naming/Sample-Makefile b/contrib/auto-naming/Sample-Makefile deleted file mode 100644 index e3e0351df8..0000000000 --- a/contrib/auto-naming/Sample-Makefile +++ /dev/null @@ -1,20 +0,0 @@ - -all: ../approved-routers - -update: - wget -q -O - http://tor.noreply.org/tor/status-vote/current/consensus | \ - ./process-consensus - -.PHONY: approved-routers-auto -approved-routers-auto: - ./build-approved-routers > "$@" - -.INTERMEDIATE: approved-routers -approved-routers: approved-routers-auto /etc/tor/approved-routers - cat $^ > "$@" - -../approved-routers: approved-routers - if ! diff -q "$<" "$@"; then \ - mv "$<" "$@" &&\ - (! [ -e /var/run/tor/tor.pid ] || kill -HUP `cat /var/run/tor/tor.pid`) ; \ - fi diff --git a/contrib/auto-naming/Sample-crontab b/contrib/auto-naming/Sample-crontab deleted file mode 100644 index b50c07bb81..0000000000 --- a/contrib/auto-naming/Sample-crontab +++ /dev/null @@ -1,3 +0,0 @@ -MAILTO=admin -# cronjob for tor naming -23 * * * * make -s -C auto-naming update && make -s -C auto-naming diff --git a/contrib/auto-naming/build-approved-routers b/contrib/auto-naming/build-approved-routers deleted file mode 100755 index 805321f208..0000000000 --- a/contrib/auto-naming/build-approved-routers +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/ruby - -# build-approved-routers - create a name-binding list for use at a Tor -# directory authority -# -# Copyright (c) 2007 Peter Palfrader -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -require "yaml" - -require 'db' -require 'db-config' - -verbose = ARGV.first == "-v" - -db = Db.new($CONFIG['database']['dbhost'], $CONFIG['database']['dbname'], $CONFIG['database']['user'], $CONFIG['database']['password']) - -db.transaction_begin -named = db.query2(" - SELECT fingerprint, router_id, nickname_id, nick, first_seen, last_seen - FROM router NATURAL JOIN router_claims_nickname NATURAL JOIN nickname - WHERE named") -while (n=named.next) do - puts "# (r##{n['router_id']},n##{n['nickname_id']}); first_seen: #{n['first_seen']}, last_seen: #{n['last_seen']}" - fpr = n['fingerprint'].split(/(....)/).delete_if{|x| x=="" }.join(' ') - puts "#{n['nick']} #{fpr}" -end -db.transaction_commit diff --git a/contrib/auto-naming/create-db.sql b/contrib/auto-naming/create-db.sql deleted file mode 100644 index 86e3e63911..0000000000 --- a/contrib/auto-naming/create-db.sql +++ /dev/null @@ -1,50 +0,0 @@ - -CREATE TABLE router ( - router_id SERIAL PRIMARY KEY, - fingerprint CHAR(40) NOT NULL, - UNIQUE(fingerprint) -); --- already created implicitly due to unique contraint --- CREATE INDEX router_fingerprint ON router(fingerprint); - -CREATE TABLE nickname ( - nickname_id SERIAL PRIMARY KEY, - nick VARCHAR(30) NOT NULL, - UNIQUE(nick) -); --- already created implicitly due to unique contraint --- CREATE INDEX nickname_nick ON nickname(nick); - -CREATE TABLE router_claims_nickname ( - router_id INTEGER NOT NULL REFERENCES router(router_id) ON DELETE CASCADE, - nickname_id INTEGER NOT NULL REFERENCES nickname(nickname_id) ON DELETE CASCADE, - first_seen TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, - last_seen TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP, - named BOOLEAN NOT NULL DEFAULT 'false', - UNIQUE(router_id, nickname_id) -); -CREATE INDEX router_claims_nickname_router_id ON router_claims_nickname(router_id); -CREATE INDEX router_claims_nickname_nickname_id ON router_claims_nickname(nickname_id); -CREATE INDEX router_claims_nickname_first_seen ON router_claims_nickname(first_seen); -CREATE INDEX router_claims_nickname_last_seen ON router_claims_nickname(last_seen); - - --- Copyright (c) 2007 Peter Palfrader --- --- Permission is hereby granted, free of charge, to any person obtaining a copy --- of this software and associated documentation files (the "Software"), to deal --- in the Software without restriction, including without limitation the rights --- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell --- copies of the Software, and to permit persons to whom the Software is --- furnished to do so, subject to the following conditions: --- --- The above copyright notice and this permission notice shall be included in --- all copies or substantial portions of the Software. --- --- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR --- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, --- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE --- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER --- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, --- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE --- SOFTWARE. diff --git a/contrib/auto-naming/db-config.rb b/contrib/auto-naming/db-config.rb deleted file mode 100644 index b1508c1b70..0000000000 --- a/contrib/auto-naming/db-config.rb +++ /dev/null @@ -1,8 +0,0 @@ -$CONFIG = {} unless $CONFIG -$CONFIG['database'] = {} unless $CONFIG['database'] - -# if you use postgres' "ident sameuser" auth set dbhost to '' -$CONFIG['database']['dbhost'] = 'localhost'; -$CONFIG['database']['dbname'] = 'tornaming'; -$CONFIG['database']['user'] = 'tornaming'; -$CONFIG['database']['password'] = 'x'; diff --git a/contrib/auto-naming/db.rb b/contrib/auto-naming/db.rb deleted file mode 100644 index 822a26bad7..0000000000 --- a/contrib/auto-naming/db.rb +++ /dev/null @@ -1,165 +0,0 @@ -#!/usr/bin/ruby - -# Copyright (c) 2006, 2007 Peter Palfrader -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -require "dbi" - -class WeaselDbQueryHandle - def initialize(sth) - @sth = sth - end - - def next() - row = @sth.fetch_hash - if row - return row - else - @sth.finish - return nil - end - end -end - -class Db - def initialize(host, database, user, password) - @dbh = DBI.connect("dbi:Pg:#{database}:#{host}", user, password); - @dbh['AutoCommit'] = false - @transaction = false - @pre_initial_transaction=true - end - - def do(query,*args) - @dbh.do(query,*args) - end - def transaction_begin() - @dbh.do("BEGIN") unless @pre_initial_transaction - @transaction = true - @pre_initial_transaction=false - end - def transaction_commit() - @dbh.do("COMMIT") - @transaction = false - end - def transaction_rollback() - @dbh.do("ROLLBACK") - end - def get_primarykey_name(table); - #return 'ref'; - return table+'_id'; - end - - def update(table, values, keys) - cols = [] - vals = [] - values.each_pair{ |k,v| - cols << "#{k}=?" - vals << v - } - - wheres = [] - keys.each_pair{ |k,v| - wheres << "#{k}=?" - vals << v - } - - throw "update value set empty" unless cols.size > 0 - throw "where clause empty" unless wheres.size > 0 - - query = "UPDATE #{table} SET #{cols.join(',')} WHERE #{wheres.join(' AND ')}" - transaction_begin unless transaction_before=@transaction - r = @dbh.do(query, *vals) - transaction_commit unless transaction_before - return r - end - - def update_row(table, values) - pk_name = get_primarykey_name(table); - throw "Ref not defined" unless values[pk_name] - return update(table, values.clone.delete_if{|k,v| k == pk_name}, { pk_name => values[pk_name] }); - end - def insert(table, values) - cols = values.keys - vals = values.values - qmarks = values.values.collect{ '?' } - - query = "INSERT INTO #{table} (#{cols.join(',')}) VALUES (#{qmarks.join(',')})" - transaction_begin unless transaction_before=@transaction - @dbh.do(query, *vals) - transaction_commit unless transaction_before - end - - def insert_row(table, values) - pk_name = get_primarykey_name(table); - if values[pk_name] - insert(table, values) - else - transaction_begin unless transaction_before=@transaction - row = query_row("SELECT nextval(pg_get_serial_sequence('#{table}', '#{pk_name}')) AS newref"); - throw "No newref?" unless row['newref'] - values[pk_name] = row['newref'] - insert(table, values); - transaction_commit unless transaction_before - end - end - def delete_row(table, ref) - pk_name = get_primarykey_name(table); - query = "DELETE FROM #{table} WHERE #{pk_name}=?" - transaction_begin unless transaction_before=@transaction - @dbh.do(query, ref) - transaction_commit unless transaction_before - end - def query(query, *params) - sth = @dbh.execute(query, *params) - while row = sth.fetch_hash - yield row - end - sth.finish - end - # nil if no results - # hash if one match - # throw otherwise - def query_row(query, *params) - sth = @dbh.execute(query, *params) - - row = sth.fetch_hash - if row == nil - sth.finish - return nil - elsif sth.fetch_hash != nil - sth.finish - throw "More than one result when querying for #{query}" - else - sth.finish - return row - end - end - def query_all(query, *params) - sth = @dbh.execute(query, *params) - - rows = sth.fetch_all - return nil if rows.size == 0 - return rows - end - def query2(query, *params) - sth = @dbh.execute(query, *params) - return WeaselDbQueryHandle.new(sth) - end -end diff --git a/contrib/auto-naming/process-consensus b/contrib/auto-naming/process-consensus deleted file mode 100755 index dc9d207e43..0000000000 --- a/contrib/auto-naming/process-consensus +++ /dev/null @@ -1,119 +0,0 @@ -#!/usr/bin/ruby - -# process-consensus - read a current consensus document, inserting the -# information into a database then calling -# update-named-status.rb to update the name-binding -# flags -# -# Copyright (c) 2007 Peter Palfrader -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -require "yaml" - -require 'db' -require 'db-config' -require 'update-named-status' - -$db = Db.new($CONFIG['database']['dbhost'], $CONFIG['database']['dbname'], $CONFIG['database']['user'], $CONFIG['database']['password']) - -$router_cache = {} -$nickname_cache = {} - -def parse_consensus consensus - ts = nil - routers = [] - consensus.each do |line| - (key, value) = line.split(' ',2) - case key - when "valid-after", "published": ts = DateTime.parse(value) - when "r": - (nick, fpr, _) = value.split(' ', 3) - nick.downcase! - next if nick == 'unnamed' - routers << { - 'nick' => nick, - 'fingerprint' => (fpr+'=').unpack('m').first.unpack('H*').first - } - end - end - throw "Did not find a timestamp" unless ts - throw "Did not find any routers" unless routers.size > 0 - return ts, routers -end - -def insert_routers_into_db(router, table, field, value) - pk = table+'_id' - row = $db.query_row("SELECT #{pk} FROM #{table} WHERE #{field}=?", value) - if row - return row[pk] - else - r = { field => value } - $db.insert_row( table, r ) - return r[pk] - end -end - -def handle_one_consensus(c) - puts "parsing..." if $verbose - timestamp, routers = parse_consensus c - puts "storing..." if $verbose - - routers.each do |router| - fpr = router['fingerprint'] - nick = router['nick'] - $router_cache[fpr] = router_id = ($router_cache[fpr] or insert_routers_into_db(router, 'router', 'fingerprint', router['fingerprint'])) - $nickname_cache[nick] = nickname_id = ($nickname_cache[nick] or insert_routers_into_db(router, 'nickname', 'nick', router['nick'])) - - row = $db.update( - 'router_claims_nickname', - { 'last_seen' => timestamp.to_s }, - { 'router_id' => router_id, 'nickname_id' => nickname_id} ) - case row - when 0: - $db.insert('router_claims_nickname', - { - 'first_seen' => timestamp.to_s, - 'last_seen' => timestamp.to_s, - 'router_id' => router_id, 'nickname_id' => nickname_id} ) - when 1: - else - throw "Update of router_claims_nickname returned unexpected number of affected rows(#{row})" - end - end -end - -$db.transaction_begin -if ARGV.first == '-v' - $verbose = true - ARGV.shift -end - -if ARGV.size == 0 - handle_one_consensus STDIN.readlines - do_update $verbose -else - ARGV.each do |filename| - puts filename if $verbose - handle_one_consensus File.new(filename).readlines - puts "updating..." if $verbose - do_update $verbose - end -end -$db.transaction_commit diff --git a/contrib/auto-naming/update-named-status.rb b/contrib/auto-naming/update-named-status.rb deleted file mode 100755 index b58b24d58f..0000000000 --- a/contrib/auto-naming/update-named-status.rb +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/ruby - -# update-named-status.rb - update the named status of routers in our database -# -# Copyright (c) 2007 Peter Palfrader -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -require "yaml" - -require 'db' -require 'db-config' - -def do_update(verbose) - now = $db.query_row("SELECT max(last_seen) AS max FROM router_claims_nickname")['max'] - unless now - STDERR.puts "Could not find the latest last_seen timestamp. Is the database empty still?" - return - end - now = "TIMESTAMP '" + now.to_s + "'" - - denamed = $db.do(" - UPDATE router_claims_nickname - SET named=false - WHERE named - AND last_seen < #{now} - INTERVAL '6 months'") - puts "de-named: #{denamed}" if verbose - - named = $db.do(" - UPDATE router_claims_nickname - SET named=true - WHERE NOT named - AND first_seen < #{now} - INTERVAL '2 weeks' - AND last_seen > #{now} - INTERVAL '2 days' - AND NOT EXISTS (SELECT * - FROM router_claims_nickname AS innertable - WHERE named - AND router_claims_nickname.nickname_id=innertable.nickname_id) "+ # if that nickname is already named, we lose. - " AND NOT EXISTS (SELECT * - FROM router_claims_nickname AS innertable - WHERE router_claims_nickname.nickname_id=innertable.nickname_id - AND router_claims_nickname.router_id <> innertable.router_id - AND last_seen > #{now} - INTERVAL '1 month') ") # if nobody else wanted that nickname in the last month we are set - puts "named: #{named}" if verbose -end - -if __FILE__ == $0 - $db = Db.new($CONFIG['database']['dbhost'], $CONFIG['database']['dbname'], $CONFIG['database']['user'], $CONFIG['database']['password']) - verbose = ARGV.first == "-v" - - $db.transaction_begin - do_update verbose - $db.transaction_commit -end