Module: DomainSanity
- Defined in:
- lib/domain_sanity.rb,
lib/domain_sanity/ip.rb,
lib/domain_sanity/idn.rb,
lib/domain_sanity/data.rb,
lib/domain_sanity/name.rb,
lib/domain_sanity/policy.rb,
lib/domain_sanity/reason.rb,
lib/domain_sanity/subject.rb,
lib/domain_sanity/version.rb
Overview
DomainSanity validates and inspects domain names the strict way a certificate authority must: RFC 1035 label rules, IDN/punycode handling, Public Suffix List and TLD checks, CA/Browser Forum aware wildcard rules, and IP / reserved-range / reverse-zone detection.
Scope: this is offline, structural validation only. It does NOT resolve DNS, check CAA records, verify that a name exists, or enforce certificate field lengths (e.g. CN <= 64). IDN conversion is IDNA2003-style punycode via SimpleIDN, not full UTS-46 (see DomainSanity::IDN). Those remain the caller's responsibility.
What "valid" means is governed by a Policy; pass policy: a preset symbol
(:ca_baseline, :dns_zone, :lenient), a Hash of overrides, or a Policy. The
module-level methods are the friendly front door. For several questions about
one subject, build a typed Subject once with .analyze and reuse it.
Defined Under Namespace
Modules: Data, IDN, IP, Name, RegistrableTypeFacts Classes: Hostname, IPSubject, MalformedSubject, Policy, Reason, ReverseZone, Subject, Wildcard
Constant Summary collapse
- VERSION =
"0.1.0"
Class Method Summary collapse
-
.analyze(subject, policy: :ca_baseline) ⇒ Object
A typed, lazily-memoized Subject (Hostname / Wildcard / IPSubject / ReverseZone / MalformedSubject) exposing every fact about subject.
-
.data_versions ⇒ Object
Provenance and staleness of the reference data (reserved-IP snapshot, PSL and IDNA gem versions).
- .ip?(subject) ⇒ Boolean
-
.mixed_script?(subject) ⇒ Boolean
True when any label mixes scripts in a homograph-suspicious way (Latin with Cyrillic, etc.).
- .public_ip?(subject) ⇒ Boolean
- .public_suffix(subject, policy: :ca_baseline) ⇒ Object
-
.reasons(subject, policy: :ca_baseline) ⇒ Object
Structured reasons subject is not a valid FQDN, as Reason objects (code, message, label).
- .registrable_domain(subject, policy: :ca_baseline) ⇒ Object
-
.reserved_ip?(subject) ⇒ Boolean
Private or otherwise reserved (non-public) IP.
- .reverse_zone?(subject) ⇒ Boolean
- .to_ascii(subject) ⇒ Object
- .to_unicode(subject) ⇒ Object
-
.valid?(subject, policy: :ca_baseline) ⇒ Boolean
Structurally valid FQDN with a real public TLD under the given policy.
-
.valid_tld?(subject, policy: :ca_baseline) ⇒ Boolean
True when subject is itself a recognized public suffix (eTLD), e.g.
-
.valid_wildcard?(subject, policy: :ca_baseline) ⇒ Boolean
Baseline-Requirements-valid wildcard: "*" is the whole leftmost label and the remainder is not a bare public suffix.
- .wildcard?(subject) ⇒ Boolean
Class Method Details
.analyze(subject, policy: :ca_baseline) ⇒ Object
A typed, lazily-memoized Subject (Hostname / Wildcard / IPSubject / ReverseZone / MalformedSubject) exposing every fact about subject. Named .analyze (not .inspect) so it does not shadow Object#inspect.
103 104 105 |
# File 'lib/domain_sanity.rb', line 103 def analyze(subject, policy: :ca_baseline) Subject.for(subject, policy: policy) end |
.data_versions ⇒ Object
Provenance and staleness of the reference data (reserved-IP snapshot, PSL and IDNA gem versions).
109 110 111 |
# File 'lib/domain_sanity.rb', line 109 def data_versions Data.versions end |
.ip?(subject) ⇒ Boolean
67 68 69 |
# File 'lib/domain_sanity.rb', line 67 def ip?(subject) IP.ip?(subject) end |
.mixed_script?(subject) ⇒ Boolean
True when any label mixes scripts in a homograph-suspicious way (Latin with Cyrillic, etc.). Opt in to enforcing this during validation with a policy of { require_single_script: true }.
96 97 98 |
# File 'lib/domain_sanity.rb', line 96 def mixed_script?(subject) IDN.mixed_script?(subject) end |
.public_ip?(subject) ⇒ Boolean
77 78 79 |
# File 'lib/domain_sanity.rb', line 77 def public_ip?(subject) IP.public?(subject) end |
.public_suffix(subject, policy: :ca_baseline) ⇒ Object
63 64 65 |
# File 'lib/domain_sanity.rb', line 63 def public_suffix(subject, policy: :ca_baseline) Name.public_suffix(subject, policy: policy) end |
.reasons(subject, policy: :ca_baseline) ⇒ Object
Structured reasons subject is not a valid FQDN, as Reason objects (code, message, label). Empty array means valid.
38 39 40 |
# File 'lib/domain_sanity.rb', line 38 def reasons(subject, policy: :ca_baseline) Name.reasons(subject, policy: policy) end |
.registrable_domain(subject, policy: :ca_baseline) ⇒ Object
59 60 61 |
# File 'lib/domain_sanity.rb', line 59 def registrable_domain(subject, policy: :ca_baseline) Name.registrable_domain(subject, policy: policy) end |
.reserved_ip?(subject) ⇒ Boolean
Private or otherwise reserved (non-public) IP. The BRs forbid issuing for these.
73 74 75 |
# File 'lib/domain_sanity.rb', line 73 def reserved_ip?(subject) IP.reserved?(subject) end |
.reverse_zone?(subject) ⇒ Boolean
81 82 83 |
# File 'lib/domain_sanity.rb', line 81 def reverse_zone?(subject) IP.reverse_zone?(subject) end |
.to_ascii(subject) ⇒ Object
85 86 87 |
# File 'lib/domain_sanity.rb', line 85 def to_ascii(subject) IDN.to_ascii(subject) end |
.to_unicode(subject) ⇒ Object
89 90 91 |
# File 'lib/domain_sanity.rb', line 89 def to_unicode(subject) IDN.to_unicode(subject) end |
.valid?(subject, policy: :ca_baseline) ⇒ Boolean
Structurally valid FQDN with a real public TLD under the given policy. Wildcards, IP literals, and reverse-zone names are excluded here.
32 33 34 |
# File 'lib/domain_sanity.rb', line 32 def valid?(subject, policy: :ca_baseline) Name.valid?(subject, policy: policy) end |
.valid_tld?(subject, policy: :ca_baseline) ⇒ Boolean
True when subject is itself a recognized public suffix (eTLD), e.g. "com" or "co.uk". A full name like "example.com" is not a suffix and returns false.
55 56 57 |
# File 'lib/domain_sanity.rb', line 55 def valid_tld?(subject, policy: :ca_baseline) Name.valid_tld?(subject, policy: policy) end |
.valid_wildcard?(subject, policy: :ca_baseline) ⇒ Boolean
Baseline-Requirements-valid wildcard: "*" is the whole leftmost label and the remainder is not a bare public suffix.
48 49 50 |
# File 'lib/domain_sanity.rb', line 48 def valid_wildcard?(subject, policy: :ca_baseline) Name.valid_wildcard?(subject, policy: policy) end |