From 6527ef6e607dc8f805f8f12d7ab596d989752dd4 Mon Sep 17 00:00:00 2001 From: olegphenomenon Date: Wed, 24 Nov 2021 16:40:00 +0200 Subject: [PATCH] updated dns check of dubzone --- app/interactions/actions/domain_update.rb | 140 ++++++++++------------ 1 file changed, 60 insertions(+), 80 deletions(-) diff --git a/app/interactions/actions/domain_update.rb b/app/interactions/actions/domain_update.rb index 81c9953aa..da74a538e 100644 --- a/app/interactions/actions/domain_update.rb +++ b/app/interactions/actions/domain_update.rb @@ -114,14 +114,6 @@ module Actions end end - # ============================ - # str.unpack("H*").first - # irb(main):111:0> res.answer[0].public_key.to_jwk - # => {"kty"=>:EC, "crv"=>:"P-256", "x"=>"Qib532jY06DaPgJQP9k4B8hjYGMKxgICf_QxsIxLp_A", "y"=>"A67HVgWBrj1mEkIT7OJxXAY263DFf5t7gu7a1hNUzw4", "kid"=>"rzgBwFog0-1Eopl1J9kBm0YU8lEsws_jJnh-Se8UcAg"} - # вот этат x и есть public key - # irb(main):122:0> res.answer[0].public_key.export - # => "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEQib532jY06DaPgJQP9k4B8hjYGMK\nxgICf/QxsIxLp/ADrsdWBYGuPWYSQhPs4nFcBjbrcMV/m3uC7trWE1TPDg==\n-----END PUBLIC KEY-----\n" - def prepare_resolver dns_servers = ENV['dnssec_resolver_ips'].to_s.split(',').map(&:strip) dns = Dnsruby::Resolver.new({nameserver: ['192.168.99.97']}) @@ -134,93 +126,81 @@ module Actions def validate_dnssec dns = prepare_resolver - ds_record = dns.query(@params[:domain], 'DS').answer[0].rdata - ds_digest = dns.query(@params[:domain], 'DS').answer[0].digest + subzone_records = get_dnskey_records_from_subzone(resolver: dns, hostname: @params[:domain]) + form_extension_records = extensional_dnskeys_data - p "++++++++++++++" - p ds_digest.upcase! - # @params[:dns_keys][0] - p generate_ds_digest(@params[:dns_keys][0]) - p "++++++++++++++" + validate_data(subzone_records: subzone_records, form_extension_records: form_extension_records) end - def generate_ds_digest(data) - flags_hex = int_to_hex(data[:flags].to_i) - protocol_hex = int_to_hex(data[:protocol].to_i) - alg_hex = int_to_hex(data[:alg].to_i) - public_key_hex = bin_to_hex(Base64.decode64(data[:public_key])) + def make_magic(subzone_records:, form_data:) + subzone_records.any? do |subzone_data| + subzone_data[:basic] == form_data[:basic] && + subzone_data[:public_key].include?(form_data[:public_key]) + end + end - domain = Domain.find_by(name: @params[:domain]) + def validate_data(subzone_records:, form_extension_records:) - hex = [domain.name_in_wire_format, flags_hex, protocol_hex, alg_hex, public_key_hex].join - bin = hex_to_bin(hex) + flag = false + form_extension_records.each do |form_data| + flag = make_magic(subzone_records: subzone_records, form_data: form_data) - ds_digest_type = Setting.ds_digest_type if ds_digest_type.blank? || !DS_DIGEST_TYPE.include?(ds_digest_type) - - case ds_digest_type - when 1 - ds_digest = Digest::SHA1.hexdigest(bin).upcase - when 2 - ds_digest = Digest::SHA256.hexdigest(bin).upcase + break if flag end - ds_digest + return validation_dns_key_error unless flag + + flag end - def int_to_hex(num) - num = num.to_s(16) - num.prepend('0') if num.length.odd? + def get_dnskey_records_from_subzone(resolver:, hostname:) + begin + ds_records_answers = resolver.query(hostname, 'DNSKEY').answer + + result_container = [] + + ds_records_answers.each do |ds| + next unless ds.type == Dnsruby::Types.DNSKEY + + result_container << { + basic: { + flags: ds.flags.to_s, + algorithm: ds.algorithm.code.to_s, + protocol: ds.protocol.to_s + }, + public_key: ds.public_key.export.gsub!(/\s+/, '') + } + end + + return result_container + + rescue Dnsruby::NXDomain + domain.add_epp_error('2308', nil, nil, I18n.t(:dns_policy_violation)) + end end - def hex_to_bin(num) - num.scan(/../).map(&:hex).pack('c*') + def validation_dns_key_error + domain.add_epp_error('2308', nil, nil, I18n.t(:dns_policy_violation)) end - def bin_to_hex(num) - num.each_byte.map { |b| format('%02X', b) }.join - end + def extensional_dnskeys_data + dnskeys_data = @params[:dns_keys] - # - # def validate_dnskey - # # domain = Domain.find_by(name: @params[:domain]) - # dns = prepare_resolver - # update_params_info = parse_data_from_update_request(@params[:dns_keys][0]) - # - # domain.add_epp_error('2308', nil, nil, I18n.t(:dns_policy_violation)) if domain.nameservers.empty? - # - # zone_info = parse_data_from_zonefile(dns_resolver: dns, hostname: domain.name) - # - # unless zone_info == update_params_info || zone_info.nil? - # domain.add_epp_error('2308', nil, nil, I18n.t(:dns_policy_violation)) - # end - # - # true - # end - # - # def parse_data_from_update_request(data) - # { - # flags: data[:flags], - # algorithm: data[:alg], - # protocol: data[:protocol], - # } - # end - # - # def parse_data_from_zonefile(dns_resolver:, hostname:) - # begin - # alg = dns_resolver.query(hostname, 'DS').answer[0].rdata[1] - # result = dns_resolver.query(hostname, 'DNSKEY').answer - # - # return nil if answer.empty? - # - # { - # flags: result[0].flags.to_s, - # algorithm: alg.to_s, - # protocol: result[0].protocol.to_s, - # } - # rescue Dnsruby::NXDomain - # domain.add_epp_error('2308', nil, nil, I18n.t(:dns_policy_violation)) - # end - # end + result_container = [] + + dnskeys_data.each do |ds| + result_container << { + basic: { + flags: ds[:flags].to_s, + algorithm: ds[:alg].to_s, + protocol: ds[:protocol].to_s, + }, + public_key: ds[:public_key] + } + end + + result_container + end def assign_removable_dnskey(key) dnkey = domain.dnskeys.find_by(key.except(:action))