Catching a few errors.

master
Karchnu 2020-12-13 03:56:32 +01:00
parent 0e5a2c3967
commit 5c735a2055
4 changed files with 82 additions and 6 deletions

View File

@ -17,6 +17,9 @@ dependencies:
baguette-crystal-base:
git: https://git.baguette.netlib.re/Baguette/baguette-crystal-base
branch: master
ipaddress:
github: sija/ipaddress.cr
targets:
dnsmanager:

View File

@ -27,9 +27,9 @@ class DNSManager::Client < IPC::Client
# Adding a full zone.
def user_zone_add(zone : DNSManager::Storage::Zone)
request = DNSManager::Request::AddZone.new zone
request = DNSManager::Request::AddOrUpdateZone.new zone
send_now @server_fd.not_nil!, request
parse_message [ DNSManager::Response::Success ], read
parse_message [ DNSManager::Response::Success, DNSManager::Response::InvalidZone ], read
end
end

View File

@ -9,6 +9,7 @@ require "baguette-crystal-base"
require "../config"
require "./lib/*"
require "../lib"
class Context
class_property command = "not-implemented"
@ -75,7 +76,7 @@ class Actions
pp! zone
pp! @dnsmanagerd.user_zone_add zone
rescue e
puts "error for admin_maintainance #{subject}: #{e.message}"
puts "error for user_zone_add: #{e.message}"
end
end
end

View File

@ -1,3 +1,4 @@
require "ipaddress"
# Store a DNS zone.
class DNSManager::Storage::Zone
@ -39,8 +40,8 @@ class DNSManager::Storage::Zone
@rrtype = self.class.name.downcase.gsub /dnsmanager::storage::zone::/, ""
end
def get_error : Error?
nil
def get_errors : Array(Error)
[] of Error
end
end
@ -61,8 +62,38 @@ class DNSManager::Storage::Zone
end
class A < ResourceRecord
def get_errors : Array(Error)
errors = [] of Error
unless Zone.is_subdomain_valid? @name
errors << "invalid subdomain: #{@name}"
end
# TODO: impose a limit on the TTL
unless Zone.is_ipv4_address_valid? @target
errors << "target not valid ipv4: #{@target}"
end
errors
end
end
class AAAA < ResourceRecord
def get_errors : Array(Error)
errors = [] of Error
unless Zone.is_subdomain_valid? @name
errors << "invalid subdomain: #{@name}"
end
# TODO: impose a limit on the TTL
unless Zone.is_ipv6_address_valid? @target
errors << "target not valid ipv6: #{@target}"
end
errors
end
end
class TXT < ResourceRecord
end
@ -101,7 +132,7 @@ class DNSManager::Storage::Zone
end
@resources.each do |r|
if error = r.get_error
r.get_errors().each do |error|
errors << error
end
end
@ -121,5 +152,46 @@ class DNSManager::Storage::Zone
false
end
# This regex only is "good enough for now".
def self.is_subdomain_valid?(subdomain) : Bool
if subdomain =~ /^(((?!-))(xn--|_{1,1})?[a-z0-9-]{0,61}[a-z0-9]{1,1}\.)*(xn--)?[a-z0-9][a-z0-9\-]{0,60}[a-z0-9]*[a-z]+|[a-z]+|[a-z][a-z0-9]+[a-z]+$/
true
else
false
end
rescue e
Baguette::Log.error "invalid zone subdomain #{subdomain}: #{e}"
false
end
# This only is "good enough for now".
# Regex only matches for invalid characters.
def self.is_ipv4_address_valid?(address) : Bool
if ! address =~ /^[0-9\.]+$/
false
elsif ip = IPAddress::IPv4.new address
true
else
false
end
rescue e
Baguette::Log.warning "wrong IPv4 address: #{address}"
false
end
# This only is "good enough for now".
# Regex only matches for invalid characters.
def self.is_ipv6_address_valid?(address) : Bool
if ! address =~ /^[0-9a-f:]+$/
false
elsif ip = IPAddress::IPv6.new address
true
else
false
end
rescue e
Baguette::Log.warning "wrong IPv4 address: #{address}"
false
end
end