diff --git a/lib/puffy/parser.y b/lib/puffy/parser.y index 69d1ac3..a6c6bce 100644 --- a/lib/puffy/parser.y +++ b/lib/puffy/parser.y @@ -13,10 +13,8 @@ rule | variable_value_list variable_value { result = val[0] + [val[1]] } | variable_value { result = [val[0]] } - variable_value: ADDRESS { result = val[0][:value] } - | STRING { result = val[0][:value] } - | VARIABLE { result = @variables.fetch(val[0][:value]) } - | port { result = val[0] } + variable_value: host_list_item { result = val[0] } + | port { result = val[0] } service: SERVICE service_name block { @services[val[1]] = val[2] } @@ -122,10 +120,9 @@ rule | { result = {} } hosts_host: ANY hosts_port { result = [{ host: nil, port: val[1] }] } - | host hosts_port { result = [{ host: val[0], port: val[1] }] } | hosts_port { result = [{ host: nil, port: val[0] }] } + | host_list_item hosts_port { result = [{ host: val[0], port: val[1] }] } | '{' host_list '}' hosts_port { result = [{ host: val[1], port: val[3] }] } - | VARIABLE hosts_port { result = [{ host: @variables.fetch(val[0][:value]), port: val[1] }] } | SRV '(' STRING ')' { result = Resolver.instance.resolv_srv(val[2][:value]) } | APT_MIRROR '(' STRING ')' { result = Resolver.instance.resolv_apt_mirror(val[2][:value]) } @@ -151,8 +148,9 @@ rule | host_list host_list_item { result = val[0] + val[1] } | host_list_item { result = val[0] } - host_list_item: host { result = [val[0]] } - | VARIABLE { result = @variables.fetch(val[0][:value]) } + host_list_item: host { result = [val[0]] } + | VARIABLE { result = @variables.fetch(val[0][:value]) } + | AZURE_IP_RANGE '(' STRING ')' { result = Resolver.instance.resolv_azure_ip_range(val[2][:value]) } filteropts: filteropts ',' filteropt { result = val[0].merge(val[2]) } | filteropts filteropt { result = val[0].merge(val[1]) } @@ -167,6 +165,7 @@ end require 'deep_merge' require 'ipaddr' +require 'json' require 'strscan' ---- inner @@ -253,6 +252,7 @@ require 'strscan' when s.scan(/rdr-to\b/) then emit(:RDR_TO, s.matched) when s.scan(/srv\b/) then emit(:SRV, s.matched) when s.scan(/apt-mirror\b/) then emit(:APT_MIRROR, s.matched) + when s.scan(/azure-ip-range\b/) then emit(:AZURE_IP_RANGE, s.matched) when s.scan(/\d+\.\d+\.\d+\.\d+(\/\d+)?/) && ip = ipaddress?(s) then emit(:ADDRESS, ip, s.matched_size) when s.scan(/[[:xdigit:]]*:[:[:xdigit:]]+(\/\d+)?/) && ip = ipaddress?(s) then emit(:ADDRESS, ip, s.matched_size) diff --git a/lib/puffy/resolver.rb b/lib/puffy/resolver.rb index 8423401..131785c 100644 --- a/lib/puffy/resolver.rb +++ b/lib/puffy/resolver.rb @@ -56,6 +56,14 @@ def resolv_apt_mirror(url) res end + def resolv_azure_ip_range(service_name) + # https://www.microsoft.com/en-us/download/details.aspx?id=56519 + @azure_ip_range ||= JSON.parse(URI('https://download.microsoft.com/download/7/1/D/71D86715-5596-4529-9B13-DA13A5DE5B63/ServiceTags_Public_20240701.json').read) + + res = @azure_ip_range['values'].select { |service| service['name'] == service_name }[0]['properties']['addressPrefixes'] + res.map { |ip| IPAddr.new(ip) } + end + private def parse_url(url) diff --git a/spec/puffy/resolver_spec.rb b/spec/puffy/resolver_spec.rb index d3ac14d..5ba7cb0 100644 --- a/spec/puffy/resolver_spec.rb +++ b/spec/puffy/resolver_spec.rb @@ -56,5 +56,15 @@ module Puffy ]) end end + + describe '#resolv_azure_ip_range' do + it 'works' do + res = subject.resolv_azure_ip_range('ActionGroup') + + expect(res).to be_an(Array) + expect(res).not_to be_empty + expect(res.first).to be_an(IPAddr) + end + end end end