mirror of
https://github.com/internetee/registry.git
synced 2025-07-03 09:43:36 +02:00
DNSSEC refactor
This commit is contained in:
parent
6f12af5e0b
commit
3453b7f4a1
14 changed files with 150 additions and 30 deletions
|
@ -94,7 +94,14 @@ module Epp::DomainsHelper
|
||||||
def validate_domain_create_request
|
def validate_domain_create_request
|
||||||
@ph = params_hash['epp']['command']['create']['create']
|
@ph = params_hash['epp']['command']['create']['create']
|
||||||
# TODO: Verify contact presence if registrant is juridical
|
# TODO: Verify contact presence if registrant is juridical
|
||||||
xml_attrs_present?(@ph, [['name'], ['ns'], ['registrant']])
|
attrs_present = xml_attrs_present?(@ph, [['name'], ['ns'], ['registrant']])
|
||||||
|
return false unless attrs_present
|
||||||
|
|
||||||
|
if parsed_frame.css('dsData').count > 0 && parsed_frame.css('create > keyData').count > 0
|
||||||
|
epp_errors << { code: '2306', msg: I18n.t('shared.ds_data_and_key_data_must_not_exists_together') }
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
def domain_create_params
|
def domain_create_params
|
||||||
|
|
3
app/models/delegation_signer.rb
Normal file
3
app/models/delegation_signer.rb
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
class DelegationSigner < ActiveRecord::Base
|
||||||
|
has_many :dnskeys
|
||||||
|
end
|
|
@ -2,6 +2,7 @@ class Dnskey < ActiveRecord::Base
|
||||||
include EppErrors
|
include EppErrors
|
||||||
|
|
||||||
belongs_to :domain
|
belongs_to :domain
|
||||||
|
belongs_to :delegation_signer
|
||||||
|
|
||||||
validates :alg, :protocol, :flags, :public_key, presence: true
|
validates :alg, :protocol, :flags, :public_key, presence: true
|
||||||
validate :validate_algorithm
|
validate :validate_algorithm
|
||||||
|
|
|
@ -174,9 +174,48 @@ class Epp::EppDomain < Domain
|
||||||
domain_statuses.delete(to_delete)
|
domain_statuses.delete(to_delete)
|
||||||
end
|
end
|
||||||
|
|
||||||
def attach_dnskeys(dnskey_list)
|
def attach_dnskeys(dnssec_data)
|
||||||
dnskey_list.each do |dnskey_attrs|
|
sg = SettingGroup.dnskeys
|
||||||
dnskeys.build(dnskey_attrs)
|
ds_data_allowed = sg.setting(Setting::ALLOW_DS_DATA) == '0' ? false : true
|
||||||
|
ds_data_with_keys_allowed = sg.setting(Setting::ALLOW_DS_DATA_WITH_KEYS) == '0' ? false : true
|
||||||
|
key_data_allowed = sg.setting(Setting::ALLOW_KEY_DATA) == '0' ? false : true
|
||||||
|
|
||||||
|
if dnssec_data[:ds_data].any? && !ds_data_allowed
|
||||||
|
errors.add(:base, :ds_data_not_allowed)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
dnssec_data[:ds_data].each do |ds_data|
|
||||||
|
if ds_data[:key_data].any? && !ds_data_with_keys_allowed
|
||||||
|
errors.add(:base, :ds_data_with_keys_not_allowed)
|
||||||
|
next
|
||||||
|
else
|
||||||
|
attach_ds(ds_data)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if dnssec_data[:key_data].any? && !key_data_allowed
|
||||||
|
errors.add(:base, :key_data_not_allowed)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
attach_ds({
|
||||||
|
keyTag: SecureRandom.hex(5),
|
||||||
|
alg: 3,
|
||||||
|
digestType: sg.setting(Setting::DS_ALGORITHM),
|
||||||
|
key_data: dnssec_data[:key_data]
|
||||||
|
})
|
||||||
|
|
||||||
|
# dnskey_list.each do |dnskey_attrs|
|
||||||
|
# dnskeys.build(dnskey_attrs)
|
||||||
|
# end
|
||||||
|
end
|
||||||
|
|
||||||
|
def attach_ds(ds_data)
|
||||||
|
key_data = ds_data.delete(:key_data)
|
||||||
|
ds = delegation_signers.build(ds_data)
|
||||||
|
key_data.each do |x|
|
||||||
|
ds.dnskeys.build(x)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -358,16 +397,39 @@ class Epp::EppDomain < Domain
|
||||||
end
|
end
|
||||||
|
|
||||||
def parse_dnskeys_from_frame(parsed_frame)
|
def parse_dnskeys_from_frame(parsed_frame)
|
||||||
res = []
|
res = { ds_data: [], key_data: [] }
|
||||||
|
|
||||||
parsed_frame.css('dnskey').each do |x|
|
res[:max_sig_life] = parsed_frame.css('maxSigLife').first.try(:text)
|
||||||
res << {
|
|
||||||
|
parsed_frame.css('dsData').each do |x|
|
||||||
|
keys = []
|
||||||
|
x.css('keyData').each do |kd|
|
||||||
|
keys << {
|
||||||
|
flags: kd.css('flags').first.try(:text),
|
||||||
|
protocol: kd.css('protocol').first.try(:text),
|
||||||
|
alg: kd.css('alg').first.try(:text),
|
||||||
|
public_key: kd.css('pubKey').first.try(:text)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
res[:ds_data] << {
|
||||||
|
key_tag: x.css('keyTag').first.try(:text),
|
||||||
|
alg: x.css('alg').first.try(:text),
|
||||||
|
digest_type: x.css('digestType').first.try(:text),
|
||||||
|
digest: x.css('digest').first.try(:text),
|
||||||
|
key_data: keys
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
parsed_frame.css('create > keyData').each do |x|
|
||||||
|
res[:key_data] << {
|
||||||
flags: x.css('flags').first.try(:text),
|
flags: x.css('flags').first.try(:text),
|
||||||
protocol: x.css('protocol').first.try(:text),
|
protocol: x.css('protocol').first.try(:text),
|
||||||
alg: x.css('alg').first.try(:text),
|
alg: x.css('alg').first.try(:text),
|
||||||
public_key: x.css('pubKey').first.try(:text)
|
public_key: x.css('pubKey').first.try(:text)
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
res
|
res
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -3,4 +3,10 @@ class Setting < ActiveRecord::Base
|
||||||
has_many :domain_statuses
|
has_many :domain_statuses
|
||||||
has_many :domains, through: :domain_statuses
|
has_many :domains, through: :domain_statuses
|
||||||
validates :code, uniqueness: { scope: :setting_group_id }
|
validates :code, uniqueness: { scope: :setting_group_id }
|
||||||
|
|
||||||
|
#dnskeys
|
||||||
|
DS_ALGORITHM = 'ds_algorithm'
|
||||||
|
ALLOW_DS_DATA = 'allow_ds_data'
|
||||||
|
ALLOW_DS_DATA_WITH_KEYS = 'allow_ds_data_with_keys'
|
||||||
|
ALLOW_KEY_DATA = 'allow_key_data'
|
||||||
end
|
end
|
||||||
|
|
|
@ -14,12 +14,12 @@ class SettingGroup < ActiveRecord::Base
|
||||||
find_by(code: 'domain_validation')
|
find_by(code: 'domain_validation')
|
||||||
end
|
end
|
||||||
|
|
||||||
def domain_statuses
|
|
||||||
find_by(code: 'domain_statuses')
|
|
||||||
end
|
|
||||||
|
|
||||||
def domain_general
|
def domain_general
|
||||||
find_by(code: 'domain_general')
|
find_by(code: 'domain_general')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def dnskeys
|
||||||
|
find_by(code: 'dnskeys')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -74,6 +74,9 @@ en:
|
||||||
base:
|
base:
|
||||||
domain_status_prohibits_operation: 'Domain status prohibits operation'
|
domain_status_prohibits_operation: 'Domain status prohibits operation'
|
||||||
domain_already_belongs_to_the_querying_registrar: 'Domain already belongs to the querying registrar'
|
domain_already_belongs_to_the_querying_registrar: 'Domain already belongs to the querying registrar'
|
||||||
|
ds_data_not_allowed: 'dsData object is not allowed'
|
||||||
|
ds_data_with_keys_not_allowed: 'dsData object with key data is not allowed'
|
||||||
|
key_data_not_allowed: 'keyData object is not allowed'
|
||||||
name_dirty:
|
name_dirty:
|
||||||
invalid: 'Domain name is invalid'
|
invalid: 'Domain name is invalid'
|
||||||
reserved: 'Domain name is reserved or restricted'
|
reserved: 'Domain name is reserved or restricted'
|
||||||
|
@ -424,3 +427,4 @@ en:
|
||||||
|
|
||||||
# sorry these need to be refactored - Andres
|
# sorry these need to be refactored - Andres
|
||||||
authentication_error: 'Authentication error'
|
authentication_error: 'Authentication error'
|
||||||
|
ds_data_and_key_data_must_not_exists_together: 'dsData and keyData objects must not exists together'
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
class AddDnskeySettings < ActiveRecord::Migration
|
class AddDnskeySettings < ActiveRecord::Migration
|
||||||
def change
|
def change
|
||||||
sg = SettingGroup.create(code: 'dnskeys')
|
sg = SettingGroup.create(code: 'dnskeys')
|
||||||
sg.settings << Setting.create(code: 'ds_algorithm', value: 1)
|
sg.settings << Setting.create(code: Setting::DS_ALGORITHM, value: 1)
|
||||||
sg.settings << Setting.create(code: 'allow_ds_data', value: 1)
|
sg.settings << Setting.create(code: Setting::ALLOW_DS_DATA, value: 1)
|
||||||
sg.settings << Setting.create(code: 'allow_ds_data_with_keys', value: 1)
|
sg.settings << Setting.create(code: Setting::ALLOW_DS_DATA_WITH_KEYS, value: 1)
|
||||||
sg.settings << Setting.create(code: 'allow_key_data', value: 1)
|
sg.settings << Setting.create(code: Setting::ALLOW_KEY_DATA, value: 1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
10
db/migrate/20141009100818_create_delegation_signer.rb
Normal file
10
db/migrate/20141009100818_create_delegation_signer.rb
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
class CreateDelegationSigner < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
create_table :delegation_signers do |t|
|
||||||
|
t.integer :domain_id
|
||||||
|
t.string :key_tag
|
||||||
|
t.integer :digest_type
|
||||||
|
t.string :digest
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,5 @@
|
||||||
|
class AddDelegationSignerToDnskey < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
add_column :dnskeys, :delegation_signer_id, :integer
|
||||||
|
end
|
||||||
|
end
|
10
db/schema.rb
10
db/schema.rb
|
@ -11,7 +11,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 20141008134959) do
|
ActiveRecord::Schema.define(version: 20141009101337) do
|
||||||
|
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
enable_extension "plpgsql"
|
||||||
|
@ -91,12 +91,20 @@ ActiveRecord::Schema.define(version: 20141008134959) do
|
||||||
t.datetime "updated_at"
|
t.datetime "updated_at"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
create_table "delegation_signers", force: true do |t|
|
||||||
|
t.integer "domain_id"
|
||||||
|
t.string "key_tag"
|
||||||
|
t.integer "digest_type"
|
||||||
|
t.string "digest"
|
||||||
|
end
|
||||||
|
|
||||||
create_table "dnskeys", force: true do |t|
|
create_table "dnskeys", force: true do |t|
|
||||||
t.integer "domain_id"
|
t.integer "domain_id"
|
||||||
t.integer "flags"
|
t.integer "flags"
|
||||||
t.integer "protocol"
|
t.integer "protocol"
|
||||||
t.integer "alg"
|
t.integer "alg"
|
||||||
t.string "public_key"
|
t.string "public_key"
|
||||||
|
t.integer "delegation_signer_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "domain_contacts", force: true do |t|
|
create_table "domain_contacts", force: true do |t|
|
||||||
|
|
|
@ -13,6 +13,7 @@ describe 'EPP Domain', epp: true do
|
||||||
|
|
||||||
Fabricate(:domain_validation_setting_group)
|
Fabricate(:domain_validation_setting_group)
|
||||||
Fabricate(:domain_statuses_setting_group)
|
Fabricate(:domain_statuses_setting_group)
|
||||||
|
Fabricate(:dnskeys_setting_group)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns error if contact does not exists' do
|
it 'returns error if contact does not exists' do
|
||||||
|
@ -324,18 +325,17 @@ describe 'EPP Domain', epp: true do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'creates a domain with multiple dnskeys' do
|
it 'creates a domain with multiple dnskeys' do
|
||||||
xml = domain_create_xml({
|
xml = domain_create_xml({}, {
|
||||||
dnssec: [
|
_other: [
|
||||||
{
|
{ keyData: {
|
||||||
dnskey: {
|
|
||||||
flags: { value: '257' },
|
flags: { value: '257' },
|
||||||
protocol: { value: '3' },
|
protocol: { value: '3' },
|
||||||
alg: { value: '3' },
|
alg: { value: '5' },
|
||||||
pubKey: { value: 'AwEAAddt2AkLfYGKgiEZB5SmIF8EvrjxNMH6HtxWEA4RJ9Ao6LCWheg8' }
|
pubKey: { value: 'AwEAAddt2AkLfYGKgiEZB5SmIF8EvrjxNMH6HtxWEA4RJ9Ao6LCWheg8' }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
dnskey: {
|
keyData: {
|
||||||
flags: { value: '0' },
|
flags: { value: '0' },
|
||||||
protocol: { value: '3' },
|
protocol: { value: '3' },
|
||||||
alg: { value: '5' },
|
alg: { value: '5' },
|
||||||
|
@ -343,7 +343,7 @@ describe 'EPP Domain', epp: true do
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
dnskey: {
|
keyData: {
|
||||||
flags: { value: '256' },
|
flags: { value: '256' },
|
||||||
protocol: { value: '3' },
|
protocol: { value: '3' },
|
||||||
alg: { value: '254' },
|
alg: { value: '254' },
|
||||||
|
|
|
@ -38,3 +38,15 @@ Fabricator(:domain_general_setting_group, from: :setting_group) do
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Fabricator(:dnskeys_setting_group, from: :setting_group) do
|
||||||
|
code 'dnskeys'
|
||||||
|
settings do
|
||||||
|
[
|
||||||
|
Fabricate(:setting, code: Setting::DS_ALGORITHM, value: 1),
|
||||||
|
Fabricate(:setting, code: Setting::ALLOW_DS_DATA, value: 1),
|
||||||
|
Fabricate(:setting, code: Setting::ALLOW_DS_DATA_WITH_KEYS, value: 1),
|
||||||
|
Fabricate(:setting, code: Setting::ALLOW_KEY_DATA, value: 1)
|
||||||
|
]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
|
@ -72,12 +72,14 @@ module Epp
|
||||||
xml_params = defaults.deep_merge(xml_params)
|
xml_params = defaults.deep_merge(xml_params)
|
||||||
|
|
||||||
dsnsec_defaults = {
|
dsnsec_defaults = {
|
||||||
keyData: [
|
_other: [
|
||||||
|
{ keyData: {
|
||||||
flags: { value: '257' },
|
flags: { value: '257' },
|
||||||
protocol: { value: '3' },
|
protocol: { value: '3' },
|
||||||
alg: { value: '5' },
|
alg: { value: '5' },
|
||||||
pubKey: { value: 'AwEAAddt2AkLfYGKgiEZB5SmIF8EvrjxNMH6HtxWEA4RJ9Ao6LCWheg8' }
|
pubKey: { value: 'AwEAAddt2AkLfYGKgiEZB5SmIF8EvrjxNMH6HtxWEA4RJ9Ao6LCWheg8' }
|
||||||
]
|
}
|
||||||
|
}]
|
||||||
}
|
}
|
||||||
|
|
||||||
dnssec_params = dsnsec_defaults.deep_merge(dnssec_params) if dnssec_params != false
|
dnssec_params = dsnsec_defaults.deep_merge(dnssec_params) if dnssec_params != false
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue