Lint fixes

This commit is contained in:
niten 2023-01-29 10:09:46 -08:00
parent 178b03e1ce
commit fc83373d6b

View File

@ -1,64 +1,65 @@
# frozen_string_literal: true
require "ipaddr" require 'ipaddr'
require "socket" require 'socket'
require "optparse" require 'optparse'
require "json" require 'json'
require "securerandom" require 'securerandom'
require 'xmpp4r'
require "xmpp4r"
puts ARGV
options = { options = {
sshfp: [] sshfp: []
} }
# rubocop:disable Metrics/BlockLength
OptionParser.new do |opts| OptionParser.new do |opts|
opts.banner = "usage: ${$0} [opts]" opts.banner = 'usage: ${$0} [opts]'
opts.on("-i", "--interface=INTERFACE", opts.on('-i', '--interface=INTERFACE',
"Publicly-accessible interface") do |interface| 'Publicly-accessible interface') do |interface|
options[:interface] = interface options[:interface] = interface
end end
opts.on("-d", "--domain=DOMAIN", opts.on('-d', '--domain=DOMAIN',
"Domain on which we wish to set the new ip") do |domain| 'Domain on which we wish to set the new ip') do |domain|
options[:domain] = domain options[:domain] = domain
end end
opts.on("-s", "--server=SERVER", opts.on('-s', '--server=SERVER',
"Backplane DNS XMPP server") do |server| 'Backplane DNS XMPP server') do |server|
options[:server] = server options[:server] = server
end end
opts.on("-p", "--password-file=/path/to/file", opts.on('-p', '--password-file=/path/to/file',
"File containing password for XMPP server") do |pw_file| 'File containing password for XMPP server') do |pw_file|
options[:pw_file] = pw_file options[:pw_file] = pw_file
end end
opts.on("-4", "--ipv4", opts.on('-4', '--ipv4',
"Check for a public IPv4 and register with the backplane.") do 'Check for a public IPv4 and register with the backplane.') do
options[:ipv4] = true options[:ipv4] = true
end end
opts.on("-6", "--ipv6", opts.on('-6', '--ipv6',
"Check for a public IPv6 and register with the backplane.") do 'Check for a public IPv6 and register with the backplane.') do
options[:ipv6] = true options[:ipv6] = true
end end
opts.on("-f", "--ssh-fp=SSHFP", "SSH fingerprint to register with he backplane.") do |fp| opts.on('-f', '--ssh-fp=SSHFP', 'SSH fingerprint to register with he backplane.') do |sshfp|
options[:sshfp] << sshfp options[:sshfp] << sshfp
end end
end.parse! end.parse!
# rubocop:enable Metrics/BlockLength
raise "domain is required" unless options[:domain] raise 'domain is required' unless options[:domain]
raise "server is required" unless options[:server] raise 'server is required' unless options[:server]
raise "password file is required" unless options[:pw_file] raise 'password file is required' unless options[:pw_file]
raise "at least one of -4 or -6 required" unless (options[:ipv4] or options[:ipv6]) raise 'at least one of -4 or -6 required' unless options[:ipv4] || options[:ipv6]
password = options[:pw_file] password = options[:pw_file]
raise "file does not exist or is not readable: #{password}" unless File::readable?(password) raise "file does not exist or is not readable: #{password}" unless File::readable?(password)
# XMPP client for Fudo Backplane
class XMPPClient class XMPPClient
def initialize(domain, hostname, server, password) def initialize(domain, hostname, server, password)
@jid = "host-#{hostname}@#{server}" @jid = "host-#{hostname}@#{server}"
@ -74,7 +75,7 @@ class XMPPClient
disconnect if connected? disconnect if connected?
@client = Jabber::Client::new(@jid) @client = Jabber::Client::new(@jid)
@client.connect # will use SRV records @client.connect # will use SRV records
error("failed to initialize TLS connection") unless @client.is_tls? error('failed to initialize TLS connection') unless @client.is_tls?
@client.auth(@password) @client.auth(@password)
register_response_callback register_response_callback
end end
@ -104,7 +105,7 @@ class XMPPClient
@client.send(msg) @client.send(msg)
response = receive_response(msg_id) response = receive_response(msg_id)
puts "response: #{response}" puts "response: #{response}"
response and response["status"] == "OK" response && response['status'] == 'OK'
end end
def send_ip(ip) def send_ip(ip)
@ -132,11 +133,11 @@ class XMPPClient
} }
end end
def sshfp_payload(fp) def sshfp_payload(fingerprint)
{ {
request: :change_sshfp, request: :change_sshfp,
domain: @domain, domain: @domain,
sshfp: fp sshfp: fingerprint
} }
end end
@ -152,35 +153,36 @@ class XMPPClient
def receive_response(msg_id) def receive_response(msg_id)
msg = @responses.pop msg = @responses.pop
return msg if (msg and (msg["msgid"] == msg_id.to_s)) return msg if msg && msg['msgid'] == msg_id.to_s
raise "failed to receive message: #{msg}" raise "failed to receive message: #{msg}"
end end
end end
RESERVED_V4_NETWORKS = [ RESERVED_V4_NETWORKS = [
"0.0.0.0/8", '0.0.0.0/8',
"10.0.0.0/8", '10.0.0.0/8',
"100.64.0.0/10", '100.64.0.0/10',
"127.0.0.0/8", '127.0.0.0/8',
"169.254.0.0/16", '169.254.0.0/16',
"172.16.0.0/12", '172.16.0.0/12',
"192.0.0.0/24", '192.0.0.0/24',
"192.0.2.0/24", '192.0.2.0/24',
"192.88.99.0/24", '192.88.99.0/24',
"192.168.0.0/16", '192.168.0.0/16',
"198.18.0.0/15", '198.18.0.0/15',
"198.51.100.0/24", '198.51.100.0/24',
"203.0.113.0/24", '203.0.113.0/24',
"224.0.0.0/4", '224.0.0.0/4',
"240.0.0.0/4", '240.0.0.0/4',
"255.255.255.255/32" '255.255.255.255/32'
].map { |ip| IPAddr.new(ip) } ].map { |ip| IPAddr.new(ip) }
def public_ip?(ip) def public_ip?(ip)
if (ip.ipv4?) if ip.ipv4?
not RESERVED_V4_NETWORKS.any? { |network| network.include? ip } RESERVED_V4_NETWORKS.none? { |network| network.include? ip }
elsif (ip.ipv6?) elsif ip.ipv6?
not (ip.link_local? or ip.loopback? or ip.private?) !(ip.link_local? || ip.loopback? || ip.private?)
else else
false false
end end
@ -190,30 +192,28 @@ def to_ipaddr(addrinfo)
if addrinfo.ipv4? if addrinfo.ipv4?
IPAddr.new addrinfo.ip_address IPAddr.new addrinfo.ip_address
else else
IPAddr.new(addrinfo.ip_address.split("%")[0]) IPAddr.new(addrinfo.ip_address.split('%')[0])
end end
end end
def local_addresses def local_addresses
Socket::ip_address_list.map do |addrinfo| ips = Socket::ip_address_list.map do |addrinfo|
to_ipaddr(addrinfo) to_ipaddr(addrinfo)
end.select { |ip| public_ip?(ip) } end
ips.select { |ip| public_ip?(ip) }
end end
def interface_addresses(interface) def interface_addresses(interface)
Socket::getifaddrs.select do |ifaddr| ifaddrs = Socket::getifaddrs.select do |ifaddr|
ifaddr.name == interface ifaddr.name == interface &&
end.select do |ifaddr| ifaddr.addr.ip? &&
ifaddr.addr.ip? and (ifaddr.flags & Socket::IFF_MULTICAST != 0) ifaddr.flag & Socket::IFF_MULTICAST != 0
end.map do |ifaddr|
to_ipaddr(ifaddr.addr)
end.filter do |ip|
public_ip? ip
end end
ifaddrs.map { |ifaddr| to_ipaddr(ifaddr.addr) }.filter(:public_ip?)
end end
def hostname def hostname
Socket.gethostname.split(".").first Socket.gethostname.split('.').first
end end
client = XMPPClient::new(options[:domain], client = XMPPClient::new(options[:domain],
@ -233,13 +233,13 @@ begin
end end
if options[:ipv4] if options[:ipv4]
ipv4 = addrs.find { |ip| ip.ipv4? } ipv4 = addrs.find(:ipv4?)
if ipv4 if ipv4
puts "#{options[:server]}: #{hostname}.#{options[:domain]} IN A => #{ipv4.to_s}" puts "#{options[:server]}: #{hostname}.#{options[:domain]} IN A => #{ipv4}"
if client.send_ip(ipv4) if client.send_ip(ipv4)
puts "OK" puts 'OK'
else else
puts "ERROR" puts 'ERROR'
success = false success = false
end end
else else
@ -248,13 +248,13 @@ begin
end end
if options[:ipv6] if options[:ipv6]
ipv6 = addrs.find { |ip| ip.ipv6? } ipv6 = addrs.find(:ipv6?)
if ipv6 if ipv6
puts "#{options[:server]}: #{hostname}.#{options[:domain]} IN AAAA => #{ipv6.to_s}" puts "#{options[:server]}: #{hostname}.#{options[:domain]} IN AAAA => #{ipv6}"
if client.send_ip(ipv6) if client.send_ip(ipv6)
puts "OK" puts 'OK'
else else
puts "ERROR" puts 'ERROR'
success = false success = false
end end
else else
@ -262,13 +262,13 @@ begin
end end
end end
if !options[:sshfp].empty? unless options[:sshfp].empty?
fps = options[:sshfp] fps = options[:sshfp]
puts "#{options[:server]}: #{hostname}.#{options[:domain]} IN SSHFP => #{fps}" puts "#{options[:server]}: #{hostname}.#{options[:domain]} IN SSHFP => #{fps}"
if client.send_sshfp(fps) if client.send_sshfp(fps)
puts "OK" puts 'OK'
else else
puts "ERROR" puts 'ERROR'
success = false success = false
end end
end end