add-tor (3216B)
1 #!/usr/bin/ruby 2 3 # add-tor - Add a tor fingerprint line to the approved-routers file 4 # 5 # Tor's approved-routers file is expected to be versioned using RCS. 6 # This script checks for uncommitted changes, does a checkout of the 7 # file, adds the new fingerprint with a comment stating the server's 8 # operator, and commits the file to RCS again (using -u so that the 9 # working copy is not removed. 10 # 11 # Operator and fingerprint line are read from stdin. 12 # 13 # Before adding a fingerprint line, approved-routers is checked for 14 # rough syntactical correctness. This script also checks that the 15 # nickname and fingerprint to be added do not already exist in the 16 # binding list. 17 18 19 # Copyright (c) 2006 by Peter Palfrader 20 # 21 # Permission is hereby granted, free of charge, to any person obtaining 22 # a copy of this software and associated documentation files (the 23 # "Software"), to deal in the Software without restriction, including 24 # without limitation the rights to use, copy, modify, merge, publish, 25 # distribute, sublicense, and/or sell copies of the Software, and to 26 # permit persons to whom the Software is furnished to do so, subject to 27 # the following conditions: 28 # 29 # The above copyright notice and this permission notice shall be 30 # included in all copies or substantial portions of the Software. 31 # 32 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 33 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 34 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 35 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 36 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 37 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 38 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 39 40 BINDING = '/etc/tor/approved-routers' 41 42 def mysys(cmd) 43 unless system(cmd) 44 STDERR.puts "ERROR: #{cmd} failed" 45 exit 1 46 end 47 end 48 49 def check_nick(n) 50 n =~ /^[a-zA-Z0-9]+$/ 51 end 52 53 def check_fpr(fpr) 54 fpr =~ /^([0-9A-F]{4} ){9}[0-9A-F]{4}$/ 55 end 56 57 def parse_fprline(fprline) 58 n = fprline[0 ... fprline.index(' ')] 59 f = fprline[fprline.index(' ') + 1 .. -1 ] 60 unless check_nick(n) and check_fpr(f) 61 STDERR.puts "Invalid fpr syntax '#{fprline}'" 62 exit 1 63 end 64 [n, f] 65 end 66 67 68 69 unless system("rcsdiff -q -u #{BINDING}") 70 STDERR.puts "Uncommitted changes in #{BINDING}. Aborting." 71 exit 1 72 end 73 74 puts "Checking out #{BINDING}..." 75 mysys("co -l #{BINDING}") 76 77 print "Operator: " 78 @operator = readline.chop 79 unless @operator.index('@') 80 STDERR.puts "ERROR: No @ found" 81 exit 1 82 end 83 84 print "FPR Line: " 85 @fprline = readline.chop 86 (@nickname, @fpr) = parse_fprline(@fprline) 87 88 binding = File.new(BINDING, "r+") 89 binding.readlines.each do |line| 90 line.chop! 91 next if line[0..0] == "#" 92 (n,f) = parse_fprline(line) 93 if (n == @nickname) 94 STDERR.puts 95 STDERR.puts "ERROR: Nickname #{n} already exists in #{BINDING} (fpr: #{f})" 96 exit 1 97 end 98 if (f == @fpr) 99 STDERR.puts 100 STDERR.puts "ERROR: Fpr #{f} already exists in #{BINDING} (nickname: #{n})" 101 exit 1 102 end 103 end 104 105 puts 106 puts '| # ' + @operator 107 puts '| ' + @fprline 108 puts 109 110 binding.puts '# '+@operator 111 binding.puts @fprline 112 binding.close 113 114 puts "Committing #{BINDING}..." 115 mysys("ci -u -m'Add #{@nickname}' #{BINDING}")