brew vendor-gems: commit updates.
This commit is contained in:
parent
1122fc98b9
commit
2a8fa71619
@ -9,6 +9,8 @@ $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/minitest-5.14.4/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/tzinfo-2.0.4/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/zeitwerk-2.4.2/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/activesupport-6.1.3.1/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/public_suffix-4.0.6/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/addressable-2.7.0/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ast-2.4.2/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/bindata-2.4.8/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/extensions/x86_64-darwin-14/2.6.0-static/msgpack-1.4.2"
|
||||
@ -37,7 +39,7 @@ $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/elftools-1.1.3/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/extensions/x86_64-darwin-14/2.6.0-static/hpricot-0.8.6"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/hpricot-0.8.6/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/http-cookie-1.0.3/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/mime-types-data-3.2021.0212/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/mime-types-data-3.2021.0225/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/mime-types-3.3.1/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/net-http-digest_auth-1.4.1/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/net-http-persistent-4.0.1/lib"
|
||||
@ -45,10 +47,10 @@ $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/mini_portile2-2.5.0/l
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/extensions/x86_64-darwin-14/2.6.0-static/racc-1.5.2"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/racc-1.5.2/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/nokogiri-1.11.2-x86_64-darwin/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ntlm-http-0.1.1/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubyntlm-0.6.3/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/webrick-1.7.0/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/webrobots-0.1.2/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/mechanize-2.7.7/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/mechanize-2.8.0/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/method_source-1.0.0/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/mustache-1.1.1/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/parallel-1.20.1/lib"
|
||||
|
||||
4
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.7.0/lib/addressable.rb
vendored
Normal file
4
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.7.0/lib/addressable.rb
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'addressable/uri'
|
||||
require 'addressable/template'
|
||||
27
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.7.0/lib/addressable/idna.rb
vendored
Normal file
27
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.7.0/lib/addressable/idna.rb
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# encoding:utf-8
|
||||
#--
|
||||
# Copyright (C) Bob Aman
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#++
|
||||
|
||||
|
||||
begin
|
||||
require "addressable/idna/native"
|
||||
rescue LoadError
|
||||
# libidn or the idn gem was not available, fall back on a pure-Ruby
|
||||
# implementation...
|
||||
require "addressable/idna/pure"
|
||||
end
|
||||
61
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.7.0/lib/addressable/idna/native.rb
vendored
Normal file
61
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.7.0/lib/addressable/idna/native.rb
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# encoding:utf-8
|
||||
#--
|
||||
# Copyright (C) Bob Aman
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#++
|
||||
|
||||
|
||||
require "idn"
|
||||
|
||||
module Addressable
|
||||
module IDNA
|
||||
def self.punycode_encode(value)
|
||||
IDN::Punycode.encode(value.to_s)
|
||||
end
|
||||
|
||||
def self.punycode_decode(value)
|
||||
IDN::Punycode.decode(value.to_s)
|
||||
end
|
||||
|
||||
def self.unicode_normalize_kc(value)
|
||||
IDN::Stringprep.nfkc_normalize(value.to_s)
|
||||
end
|
||||
|
||||
def self.to_ascii(value)
|
||||
value.to_s.split('.', -1).map do |segment|
|
||||
if segment.size > 0 && segment.size < 64
|
||||
IDN::Idna.toASCII(segment, IDN::Idna::ALLOW_UNASSIGNED)
|
||||
elsif segment.size >= 64
|
||||
segment
|
||||
else
|
||||
''
|
||||
end
|
||||
end.join('.')
|
||||
end
|
||||
|
||||
def self.to_unicode(value)
|
||||
value.to_s.split('.', -1).map do |segment|
|
||||
if segment.size > 0 && segment.size < 64
|
||||
IDN::Idna.toUnicode(segment, IDN::Idna::ALLOW_UNASSIGNED)
|
||||
elsif segment.size >= 64
|
||||
segment
|
||||
else
|
||||
''
|
||||
end
|
||||
end.join('.')
|
||||
end
|
||||
end
|
||||
end
|
||||
676
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.7.0/lib/addressable/idna/pure.rb
vendored
Normal file
676
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.7.0/lib/addressable/idna/pure.rb
vendored
Normal file
@ -0,0 +1,676 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# encoding:utf-8
|
||||
#--
|
||||
# Copyright (C) Bob Aman
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#++
|
||||
|
||||
|
||||
module Addressable
|
||||
module IDNA
|
||||
# This module is loosely based on idn_actionmailer by Mick Staugaard,
|
||||
# the unicode library by Yoshida Masato, and the punycode implementation
|
||||
# by Kazuhiro Nishiyama. Most of the code was copied verbatim, but
|
||||
# some reformatting was done, and some translation from C was done.
|
||||
#
|
||||
# Without their code to work from as a base, we'd all still be relying
|
||||
# on the presence of libidn. Which nobody ever seems to have installed.
|
||||
#
|
||||
# Original sources:
|
||||
# http://github.com/staugaard/idn_actionmailer
|
||||
# http://www.yoshidam.net/Ruby.html#unicode
|
||||
# http://rubyforge.org/frs/?group_id=2550
|
||||
|
||||
|
||||
UNICODE_TABLE = File.expand_path(
|
||||
File.join(File.dirname(__FILE__), '../../..', 'data/unicode.data')
|
||||
)
|
||||
|
||||
ACE_PREFIX = "xn--"
|
||||
|
||||
UTF8_REGEX = /\A(?:
|
||||
[\x09\x0A\x0D\x20-\x7E] # ASCII
|
||||
| [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
|
||||
| \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
|
||||
| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
|
||||
| \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
|
||||
| \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
|
||||
| [\xF1-\xF3][\x80-\xBF]{3} # planes 4nil5
|
||||
| \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
|
||||
)*\z/mnx
|
||||
|
||||
UTF8_REGEX_MULTIBYTE = /(?:
|
||||
[\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
|
||||
| \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
|
||||
| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
|
||||
| \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
|
||||
| \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
|
||||
| [\xF1-\xF3][\x80-\xBF]{3} # planes 4nil5
|
||||
| \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
|
||||
)/mnx
|
||||
|
||||
# :startdoc:
|
||||
|
||||
# Converts from a Unicode internationalized domain name to an ASCII
|
||||
# domain name as described in RFC 3490.
|
||||
def self.to_ascii(input)
|
||||
input = input.to_s unless input.is_a?(String)
|
||||
input = input.dup
|
||||
if input.respond_to?(:force_encoding)
|
||||
input.force_encoding(Encoding::ASCII_8BIT)
|
||||
end
|
||||
if input =~ UTF8_REGEX && input =~ UTF8_REGEX_MULTIBYTE
|
||||
parts = unicode_downcase(input).split('.')
|
||||
parts.map! do |part|
|
||||
if part.respond_to?(:force_encoding)
|
||||
part.force_encoding(Encoding::ASCII_8BIT)
|
||||
end
|
||||
if part =~ UTF8_REGEX && part =~ UTF8_REGEX_MULTIBYTE
|
||||
ACE_PREFIX + punycode_encode(unicode_normalize_kc(part))
|
||||
else
|
||||
part
|
||||
end
|
||||
end
|
||||
parts.join('.')
|
||||
else
|
||||
input
|
||||
end
|
||||
end
|
||||
|
||||
# Converts from an ASCII domain name to a Unicode internationalized
|
||||
# domain name as described in RFC 3490.
|
||||
def self.to_unicode(input)
|
||||
input = input.to_s unless input.is_a?(String)
|
||||
parts = input.split('.')
|
||||
parts.map! do |part|
|
||||
if part =~ /^#{ACE_PREFIX}(.+)/
|
||||
begin
|
||||
punycode_decode(part[/^#{ACE_PREFIX}(.+)/, 1])
|
||||
rescue Addressable::IDNA::PunycodeBadInput
|
||||
# toUnicode is explicitly defined as never-fails by the spec
|
||||
part
|
||||
end
|
||||
else
|
||||
part
|
||||
end
|
||||
end
|
||||
output = parts.join('.')
|
||||
if output.respond_to?(:force_encoding)
|
||||
output.force_encoding(Encoding::UTF_8)
|
||||
end
|
||||
output
|
||||
end
|
||||
|
||||
# Unicode normalization form KC.
|
||||
def self.unicode_normalize_kc(input)
|
||||
input = input.to_s unless input.is_a?(String)
|
||||
unpacked = input.unpack("U*")
|
||||
unpacked =
|
||||
unicode_compose(unicode_sort_canonical(unicode_decompose(unpacked)))
|
||||
return unpacked.pack("U*")
|
||||
end
|
||||
|
||||
##
|
||||
# Unicode aware downcase method.
|
||||
#
|
||||
# @api private
|
||||
# @param [String] input
|
||||
# The input string.
|
||||
# @return [String] The downcased result.
|
||||
def self.unicode_downcase(input)
|
||||
input = input.to_s unless input.is_a?(String)
|
||||
unpacked = input.unpack("U*")
|
||||
unpacked.map! { |codepoint| lookup_unicode_lowercase(codepoint) }
|
||||
return unpacked.pack("U*")
|
||||
end
|
||||
private_class_method :unicode_downcase
|
||||
|
||||
def self.unicode_compose(unpacked)
|
||||
unpacked_result = []
|
||||
length = unpacked.length
|
||||
|
||||
return unpacked if length == 0
|
||||
|
||||
starter = unpacked[0]
|
||||
starter_cc = lookup_unicode_combining_class(starter)
|
||||
starter_cc = 256 if starter_cc != 0
|
||||
for i in 1...length
|
||||
ch = unpacked[i]
|
||||
|
||||
if (starter_cc == 0 &&
|
||||
(composite = unicode_compose_pair(starter, ch)) != nil)
|
||||
starter = composite
|
||||
else
|
||||
unpacked_result << starter
|
||||
starter = ch
|
||||
end
|
||||
end
|
||||
unpacked_result << starter
|
||||
return unpacked_result
|
||||
end
|
||||
private_class_method :unicode_compose
|
||||
|
||||
def self.unicode_compose_pair(ch_one, ch_two)
|
||||
if ch_one >= HANGUL_LBASE && ch_one < HANGUL_LBASE + HANGUL_LCOUNT &&
|
||||
ch_two >= HANGUL_VBASE && ch_two < HANGUL_VBASE + HANGUL_VCOUNT
|
||||
# Hangul L + V
|
||||
return HANGUL_SBASE + (
|
||||
(ch_one - HANGUL_LBASE) * HANGUL_VCOUNT + (ch_two - HANGUL_VBASE)
|
||||
) * HANGUL_TCOUNT
|
||||
elsif ch_one >= HANGUL_SBASE &&
|
||||
ch_one < HANGUL_SBASE + HANGUL_SCOUNT &&
|
||||
(ch_one - HANGUL_SBASE) % HANGUL_TCOUNT == 0 &&
|
||||
ch_two >= HANGUL_TBASE && ch_two < HANGUL_TBASE + HANGUL_TCOUNT
|
||||
# Hangul LV + T
|
||||
return ch_one + (ch_two - HANGUL_TBASE)
|
||||
end
|
||||
|
||||
p = []
|
||||
ucs4_to_utf8 = lambda do |ch|
|
||||
if ch < 128
|
||||
p << ch
|
||||
elsif ch < 2048
|
||||
p << (ch >> 6 | 192)
|
||||
p << (ch & 63 | 128)
|
||||
elsif ch < 0x10000
|
||||
p << (ch >> 12 | 224)
|
||||
p << (ch >> 6 & 63 | 128)
|
||||
p << (ch & 63 | 128)
|
||||
elsif ch < 0x200000
|
||||
p << (ch >> 18 | 240)
|
||||
p << (ch >> 12 & 63 | 128)
|
||||
p << (ch >> 6 & 63 | 128)
|
||||
p << (ch & 63 | 128)
|
||||
elsif ch < 0x4000000
|
||||
p << (ch >> 24 | 248)
|
||||
p << (ch >> 18 & 63 | 128)
|
||||
p << (ch >> 12 & 63 | 128)
|
||||
p << (ch >> 6 & 63 | 128)
|
||||
p << (ch & 63 | 128)
|
||||
elsif ch < 0x80000000
|
||||
p << (ch >> 30 | 252)
|
||||
p << (ch >> 24 & 63 | 128)
|
||||
p << (ch >> 18 & 63 | 128)
|
||||
p << (ch >> 12 & 63 | 128)
|
||||
p << (ch >> 6 & 63 | 128)
|
||||
p << (ch & 63 | 128)
|
||||
end
|
||||
end
|
||||
|
||||
ucs4_to_utf8.call(ch_one)
|
||||
ucs4_to_utf8.call(ch_two)
|
||||
|
||||
return lookup_unicode_composition(p)
|
||||
end
|
||||
private_class_method :unicode_compose_pair
|
||||
|
||||
def self.unicode_sort_canonical(unpacked)
|
||||
unpacked = unpacked.dup
|
||||
i = 1
|
||||
length = unpacked.length
|
||||
|
||||
return unpacked if length < 2
|
||||
|
||||
while i < length
|
||||
last = unpacked[i-1]
|
||||
ch = unpacked[i]
|
||||
last_cc = lookup_unicode_combining_class(last)
|
||||
cc = lookup_unicode_combining_class(ch)
|
||||
if cc != 0 && last_cc != 0 && last_cc > cc
|
||||
unpacked[i] = last
|
||||
unpacked[i-1] = ch
|
||||
i -= 1 if i > 1
|
||||
else
|
||||
i += 1
|
||||
end
|
||||
end
|
||||
return unpacked
|
||||
end
|
||||
private_class_method :unicode_sort_canonical
|
||||
|
||||
def self.unicode_decompose(unpacked)
|
||||
unpacked_result = []
|
||||
for cp in unpacked
|
||||
if cp >= HANGUL_SBASE && cp < HANGUL_SBASE + HANGUL_SCOUNT
|
||||
l, v, t = unicode_decompose_hangul(cp)
|
||||
unpacked_result << l
|
||||
unpacked_result << v if v
|
||||
unpacked_result << t if t
|
||||
else
|
||||
dc = lookup_unicode_compatibility(cp)
|
||||
unless dc
|
||||
unpacked_result << cp
|
||||
else
|
||||
unpacked_result.concat(unicode_decompose(dc.unpack("U*")))
|
||||
end
|
||||
end
|
||||
end
|
||||
return unpacked_result
|
||||
end
|
||||
private_class_method :unicode_decompose
|
||||
|
||||
def self.unicode_decompose_hangul(codepoint)
|
||||
sindex = codepoint - HANGUL_SBASE;
|
||||
if sindex < 0 || sindex >= HANGUL_SCOUNT
|
||||
l = codepoint
|
||||
v = t = nil
|
||||
return l, v, t
|
||||
end
|
||||
l = HANGUL_LBASE + sindex / HANGUL_NCOUNT
|
||||
v = HANGUL_VBASE + (sindex % HANGUL_NCOUNT) / HANGUL_TCOUNT
|
||||
t = HANGUL_TBASE + sindex % HANGUL_TCOUNT
|
||||
if t == HANGUL_TBASE
|
||||
t = nil
|
||||
end
|
||||
return l, v, t
|
||||
end
|
||||
private_class_method :unicode_decompose_hangul
|
||||
|
||||
def self.lookup_unicode_combining_class(codepoint)
|
||||
codepoint_data = UNICODE_DATA[codepoint]
|
||||
(codepoint_data ?
|
||||
(codepoint_data[UNICODE_DATA_COMBINING_CLASS] || 0) :
|
||||
0)
|
||||
end
|
||||
private_class_method :lookup_unicode_combining_class
|
||||
|
||||
def self.lookup_unicode_compatibility(codepoint)
|
||||
codepoint_data = UNICODE_DATA[codepoint]
|
||||
(codepoint_data ?
|
||||
codepoint_data[UNICODE_DATA_COMPATIBILITY] : nil)
|
||||
end
|
||||
private_class_method :lookup_unicode_compatibility
|
||||
|
||||
def self.lookup_unicode_lowercase(codepoint)
|
||||
codepoint_data = UNICODE_DATA[codepoint]
|
||||
(codepoint_data ?
|
||||
(codepoint_data[UNICODE_DATA_LOWERCASE] || codepoint) :
|
||||
codepoint)
|
||||
end
|
||||
private_class_method :lookup_unicode_lowercase
|
||||
|
||||
def self.lookup_unicode_composition(unpacked)
|
||||
return COMPOSITION_TABLE[unpacked]
|
||||
end
|
||||
private_class_method :lookup_unicode_composition
|
||||
|
||||
HANGUL_SBASE = 0xac00
|
||||
HANGUL_LBASE = 0x1100
|
||||
HANGUL_LCOUNT = 19
|
||||
HANGUL_VBASE = 0x1161
|
||||
HANGUL_VCOUNT = 21
|
||||
HANGUL_TBASE = 0x11a7
|
||||
HANGUL_TCOUNT = 28
|
||||
HANGUL_NCOUNT = HANGUL_VCOUNT * HANGUL_TCOUNT # 588
|
||||
HANGUL_SCOUNT = HANGUL_LCOUNT * HANGUL_NCOUNT # 11172
|
||||
|
||||
UNICODE_DATA_COMBINING_CLASS = 0
|
||||
UNICODE_DATA_EXCLUSION = 1
|
||||
UNICODE_DATA_CANONICAL = 2
|
||||
UNICODE_DATA_COMPATIBILITY = 3
|
||||
UNICODE_DATA_UPPERCASE = 4
|
||||
UNICODE_DATA_LOWERCASE = 5
|
||||
UNICODE_DATA_TITLECASE = 6
|
||||
|
||||
begin
|
||||
if defined?(FakeFS)
|
||||
fakefs_state = FakeFS.activated?
|
||||
FakeFS.deactivate!
|
||||
end
|
||||
# This is a sparse Unicode table. Codepoints without entries are
|
||||
# assumed to have the value: [0, 0, nil, nil, nil, nil, nil]
|
||||
UNICODE_DATA = File.open(UNICODE_TABLE, "rb") do |file|
|
||||
Marshal.load(file.read)
|
||||
end
|
||||
ensure
|
||||
if defined?(FakeFS)
|
||||
FakeFS.activate! if fakefs_state
|
||||
end
|
||||
end
|
||||
|
||||
COMPOSITION_TABLE = {}
|
||||
UNICODE_DATA.each do |codepoint, data|
|
||||
canonical = data[UNICODE_DATA_CANONICAL]
|
||||
exclusion = data[UNICODE_DATA_EXCLUSION]
|
||||
|
||||
if canonical && exclusion == 0
|
||||
COMPOSITION_TABLE[canonical.unpack("C*")] = codepoint
|
||||
end
|
||||
end
|
||||
|
||||
UNICODE_MAX_LENGTH = 256
|
||||
ACE_MAX_LENGTH = 256
|
||||
|
||||
PUNYCODE_BASE = 36
|
||||
PUNYCODE_TMIN = 1
|
||||
PUNYCODE_TMAX = 26
|
||||
PUNYCODE_SKEW = 38
|
||||
PUNYCODE_DAMP = 700
|
||||
PUNYCODE_INITIAL_BIAS = 72
|
||||
PUNYCODE_INITIAL_N = 0x80
|
||||
PUNYCODE_DELIMITER = 0x2D
|
||||
|
||||
PUNYCODE_MAXINT = 1 << 64
|
||||
|
||||
PUNYCODE_PRINT_ASCII =
|
||||
"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" +
|
||||
"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" +
|
||||
" !\"\#$%&'()*+,-./" +
|
||||
"0123456789:;<=>?" +
|
||||
"@ABCDEFGHIJKLMNO" +
|
||||
"PQRSTUVWXYZ[\\]^_" +
|
||||
"`abcdefghijklmno" +
|
||||
"pqrstuvwxyz{|}~\n"
|
||||
|
||||
# Input is invalid.
|
||||
class PunycodeBadInput < StandardError; end
|
||||
# Output would exceed the space provided.
|
||||
class PunycodeBigOutput < StandardError; end
|
||||
# Input needs wider integers to process.
|
||||
class PunycodeOverflow < StandardError; end
|
||||
|
||||
def self.punycode_encode(unicode)
|
||||
unicode = unicode.to_s unless unicode.is_a?(String)
|
||||
input = unicode.unpack("U*")
|
||||
output = [0] * (ACE_MAX_LENGTH + 1)
|
||||
input_length = input.size
|
||||
output_length = [ACE_MAX_LENGTH]
|
||||
|
||||
# Initialize the state
|
||||
n = PUNYCODE_INITIAL_N
|
||||
delta = out = 0
|
||||
max_out = output_length[0]
|
||||
bias = PUNYCODE_INITIAL_BIAS
|
||||
|
||||
# Handle the basic code points:
|
||||
input_length.times do |j|
|
||||
if punycode_basic?(input[j])
|
||||
if max_out - out < 2
|
||||
raise PunycodeBigOutput,
|
||||
"Output would exceed the space provided."
|
||||
end
|
||||
output[out] = input[j]
|
||||
out += 1
|
||||
end
|
||||
end
|
||||
|
||||
h = b = out
|
||||
|
||||
# h is the number of code points that have been handled, b is the
|
||||
# number of basic code points, and out is the number of characters
|
||||
# that have been output.
|
||||
|
||||
if b > 0
|
||||
output[out] = PUNYCODE_DELIMITER
|
||||
out += 1
|
||||
end
|
||||
|
||||
# Main encoding loop:
|
||||
|
||||
while h < input_length
|
||||
# All non-basic code points < n have been
|
||||
# handled already. Find the next larger one:
|
||||
|
||||
m = PUNYCODE_MAXINT
|
||||
input_length.times do |j|
|
||||
m = input[j] if (n...m) === input[j]
|
||||
end
|
||||
|
||||
# Increase delta enough to advance the decoder's
|
||||
# <n,i> state to <m,0>, but guard against overflow:
|
||||
|
||||
if m - n > (PUNYCODE_MAXINT - delta) / (h + 1)
|
||||
raise PunycodeOverflow, "Input needs wider integers to process."
|
||||
end
|
||||
delta += (m - n) * (h + 1)
|
||||
n = m
|
||||
|
||||
input_length.times do |j|
|
||||
# Punycode does not need to check whether input[j] is basic:
|
||||
if input[j] < n
|
||||
delta += 1
|
||||
if delta == 0
|
||||
raise PunycodeOverflow,
|
||||
"Input needs wider integers to process."
|
||||
end
|
||||
end
|
||||
|
||||
if input[j] == n
|
||||
# Represent delta as a generalized variable-length integer:
|
||||
|
||||
q = delta; k = PUNYCODE_BASE
|
||||
while true
|
||||
if out >= max_out
|
||||
raise PunycodeBigOutput,
|
||||
"Output would exceed the space provided."
|
||||
end
|
||||
t = (
|
||||
if k <= bias
|
||||
PUNYCODE_TMIN
|
||||
elsif k >= bias + PUNYCODE_TMAX
|
||||
PUNYCODE_TMAX
|
||||
else
|
||||
k - bias
|
||||
end
|
||||
)
|
||||
break if q < t
|
||||
output[out] =
|
||||
punycode_encode_digit(t + (q - t) % (PUNYCODE_BASE - t))
|
||||
out += 1
|
||||
q = (q - t) / (PUNYCODE_BASE - t)
|
||||
k += PUNYCODE_BASE
|
||||
end
|
||||
|
||||
output[out] = punycode_encode_digit(q)
|
||||
out += 1
|
||||
bias = punycode_adapt(delta, h + 1, h == b)
|
||||
delta = 0
|
||||
h += 1
|
||||
end
|
||||
end
|
||||
|
||||
delta += 1
|
||||
n += 1
|
||||
end
|
||||
|
||||
output_length[0] = out
|
||||
|
||||
outlen = out
|
||||
outlen.times do |j|
|
||||
c = output[j]
|
||||
unless c >= 0 && c <= 127
|
||||
raise StandardError, "Invalid output char."
|
||||
end
|
||||
unless PUNYCODE_PRINT_ASCII[c]
|
||||
raise PunycodeBadInput, "Input is invalid."
|
||||
end
|
||||
end
|
||||
|
||||
output[0..outlen].map { |x| x.chr }.join("").sub(/\0+\z/, "")
|
||||
end
|
||||
private_class_method :punycode_encode
|
||||
|
||||
def self.punycode_decode(punycode)
|
||||
input = []
|
||||
output = []
|
||||
|
||||
if ACE_MAX_LENGTH * 2 < punycode.size
|
||||
raise PunycodeBigOutput, "Output would exceed the space provided."
|
||||
end
|
||||
punycode.each_byte do |c|
|
||||
unless c >= 0 && c <= 127
|
||||
raise PunycodeBadInput, "Input is invalid."
|
||||
end
|
||||
input.push(c)
|
||||
end
|
||||
|
||||
input_length = input.length
|
||||
output_length = [UNICODE_MAX_LENGTH]
|
||||
|
||||
# Initialize the state
|
||||
n = PUNYCODE_INITIAL_N
|
||||
|
||||
out = i = 0
|
||||
max_out = output_length[0]
|
||||
bias = PUNYCODE_INITIAL_BIAS
|
||||
|
||||
# Handle the basic code points: Let b be the number of input code
|
||||
# points before the last delimiter, or 0 if there is none, then
|
||||
# copy the first b code points to the output.
|
||||
|
||||
b = 0
|
||||
input_length.times do |j|
|
||||
b = j if punycode_delimiter?(input[j])
|
||||
end
|
||||
if b > max_out
|
||||
raise PunycodeBigOutput, "Output would exceed the space provided."
|
||||
end
|
||||
|
||||
b.times do |j|
|
||||
unless punycode_basic?(input[j])
|
||||
raise PunycodeBadInput, "Input is invalid."
|
||||
end
|
||||
output[out] = input[j]
|
||||
out+=1
|
||||
end
|
||||
|
||||
# Main decoding loop: Start just after the last delimiter if any
|
||||
# basic code points were copied; start at the beginning otherwise.
|
||||
|
||||
in_ = b > 0 ? b + 1 : 0
|
||||
while in_ < input_length
|
||||
|
||||
# in_ is the index of the next character to be consumed, and
|
||||
# out is the number of code points in the output array.
|
||||
|
||||
# Decode a generalized variable-length integer into delta,
|
||||
# which gets added to i. The overflow checking is easier
|
||||
# if we increase i as we go, then subtract off its starting
|
||||
# value at the end to obtain delta.
|
||||
|
||||
oldi = i; w = 1; k = PUNYCODE_BASE
|
||||
while true
|
||||
if in_ >= input_length
|
||||
raise PunycodeBadInput, "Input is invalid."
|
||||
end
|
||||
digit = punycode_decode_digit(input[in_])
|
||||
in_+=1
|
||||
if digit >= PUNYCODE_BASE
|
||||
raise PunycodeBadInput, "Input is invalid."
|
||||
end
|
||||
if digit > (PUNYCODE_MAXINT - i) / w
|
||||
raise PunycodeOverflow, "Input needs wider integers to process."
|
||||
end
|
||||
i += digit * w
|
||||
t = (
|
||||
if k <= bias
|
||||
PUNYCODE_TMIN
|
||||
elsif k >= bias + PUNYCODE_TMAX
|
||||
PUNYCODE_TMAX
|
||||
else
|
||||
k - bias
|
||||
end
|
||||
)
|
||||
break if digit < t
|
||||
if w > PUNYCODE_MAXINT / (PUNYCODE_BASE - t)
|
||||
raise PunycodeOverflow, "Input needs wider integers to process."
|
||||
end
|
||||
w *= PUNYCODE_BASE - t
|
||||
k += PUNYCODE_BASE
|
||||
end
|
||||
|
||||
bias = punycode_adapt(i - oldi, out + 1, oldi == 0)
|
||||
|
||||
# I was supposed to wrap around from out + 1 to 0,
|
||||
# incrementing n each time, so we'll fix that now:
|
||||
|
||||
if i / (out + 1) > PUNYCODE_MAXINT - n
|
||||
raise PunycodeOverflow, "Input needs wider integers to process."
|
||||
end
|
||||
n += i / (out + 1)
|
||||
i %= out + 1
|
||||
|
||||
# Insert n at position i of the output:
|
||||
|
||||
# not needed for Punycode:
|
||||
# raise PUNYCODE_INVALID_INPUT if decode_digit(n) <= base
|
||||
if out >= max_out
|
||||
raise PunycodeBigOutput, "Output would exceed the space provided."
|
||||
end
|
||||
|
||||
#memmove(output + i + 1, output + i, (out - i) * sizeof *output)
|
||||
output[i + 1, out - i] = output[i, out - i]
|
||||
output[i] = n
|
||||
i += 1
|
||||
|
||||
out += 1
|
||||
end
|
||||
|
||||
output_length[0] = out
|
||||
|
||||
output.pack("U*")
|
||||
end
|
||||
private_class_method :punycode_decode
|
||||
|
||||
def self.punycode_basic?(codepoint)
|
||||
codepoint < 0x80
|
||||
end
|
||||
private_class_method :punycode_basic?
|
||||
|
||||
def self.punycode_delimiter?(codepoint)
|
||||
codepoint == PUNYCODE_DELIMITER
|
||||
end
|
||||
private_class_method :punycode_delimiter?
|
||||
|
||||
def self.punycode_encode_digit(d)
|
||||
d + 22 + 75 * ((d < 26) ? 1 : 0)
|
||||
end
|
||||
private_class_method :punycode_encode_digit
|
||||
|
||||
# Returns the numeric value of a basic codepoint
|
||||
# (for use in representing integers) in the range 0 to
|
||||
# base - 1, or PUNYCODE_BASE if codepoint does not represent a value.
|
||||
def self.punycode_decode_digit(codepoint)
|
||||
if codepoint - 48 < 10
|
||||
codepoint - 22
|
||||
elsif codepoint - 65 < 26
|
||||
codepoint - 65
|
||||
elsif codepoint - 97 < 26
|
||||
codepoint - 97
|
||||
else
|
||||
PUNYCODE_BASE
|
||||
end
|
||||
end
|
||||
private_class_method :punycode_decode_digit
|
||||
|
||||
# Bias adaptation method
|
||||
def self.punycode_adapt(delta, numpoints, firsttime)
|
||||
delta = firsttime ? delta / PUNYCODE_DAMP : delta >> 1
|
||||
# delta >> 1 is a faster way of doing delta / 2
|
||||
delta += delta / numpoints
|
||||
difference = PUNYCODE_BASE - PUNYCODE_TMIN
|
||||
|
||||
k = 0
|
||||
while delta > (difference * PUNYCODE_TMAX) / 2
|
||||
delta /= difference
|
||||
k += PUNYCODE_BASE
|
||||
end
|
||||
|
||||
k + (difference + 1) * delta / (delta + PUNYCODE_SKEW)
|
||||
end
|
||||
private_class_method :punycode_adapt
|
||||
end
|
||||
# :startdoc:
|
||||
end
|
||||
1045
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.7.0/lib/addressable/template.rb
vendored
Normal file
1045
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.7.0/lib/addressable/template.rb
vendored
Normal file
File diff suppressed because it is too large
Load Diff
2529
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.7.0/lib/addressable/uri.rb
vendored
Normal file
2529
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.7.0/lib/addressable/uri.rb
vendored
Normal file
File diff suppressed because it is too large
Load Diff
32
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.7.0/lib/addressable/version.rb
vendored
Normal file
32
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/addressable-2.7.0/lib/addressable/version.rb
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# encoding:utf-8
|
||||
#--
|
||||
# Copyright (C) Bob Aman
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#++
|
||||
|
||||
|
||||
# Used to prevent the class/module from being loaded more than once
|
||||
if !defined?(Addressable::VERSION)
|
||||
module Addressable
|
||||
module VERSION
|
||||
MAJOR = 2
|
||||
MINOR = 7
|
||||
TINY = 0
|
||||
|
||||
STRING = [MAJOR, MINOR, TINY].join('.')
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,3 +0,0 @@
|
||||
class Mechanize
|
||||
VERSION = "2.7.7"
|
||||
end
|
||||
@ -1,3 +1,4 @@
|
||||
# frozen_string_literal: true
|
||||
# coding: BINARY
|
||||
|
||||
require 'strscan'
|
||||
@ -16,6 +17,7 @@ end
|
||||
# * Missing disposition-type
|
||||
# * Multiple semicolons
|
||||
# * Whitespace around semicolons
|
||||
# * Dates in ISO 8601 format
|
||||
|
||||
class Mechanize::HTTP::ContentDispositionParser
|
||||
|
||||
@ -93,7 +95,17 @@ class Mechanize::HTTP::ContentDispositionParser
|
||||
when /^filename$/ then
|
||||
rfc_2045_value
|
||||
when /^(creation|modification|read)-date$/ then
|
||||
Time.rfc822 rfc_2045_quoted_string
|
||||
date = rfc_2045_quoted_string
|
||||
|
||||
begin
|
||||
Time.rfc822 date
|
||||
rescue ArgumentError
|
||||
begin
|
||||
Time.iso8601 date
|
||||
rescue ArgumentError
|
||||
nil
|
||||
end
|
||||
end
|
||||
when /^size$/ then
|
||||
rfc_2045_value.to_i(10)
|
||||
else
|
||||
@ -125,7 +137,7 @@ class Mechanize::HTTP::ContentDispositionParser
|
||||
def rfc_2045_quoted_string
|
||||
return nil unless @scanner.scan(/"/)
|
||||
|
||||
text = ''
|
||||
text = String.new
|
||||
|
||||
while true do
|
||||
chunk = @scanner.scan(/[\000-\014\016-\041\043-\133\135-\177]+/) # not \r "
|
||||
4
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/mechanize-2.8.0/lib/mechanize/version.rb
vendored
Normal file
4
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/mechanize-2.8.0/lib/mechanize/version.rb
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
# frozen_string_literal: true
|
||||
class Mechanize
|
||||
VERSION = "2.8.0"
|
||||
end
|
||||
179
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/public_suffix-4.0.6/lib/public_suffix.rb
vendored
Normal file
179
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/public_suffix-4.0.6/lib/public_suffix.rb
vendored
Normal file
@ -0,0 +1,179 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# = Public Suffix
|
||||
#
|
||||
# Domain name parser based on the Public Suffix List.
|
||||
#
|
||||
# Copyright (c) 2009-2020 Simone Carletti <weppos@weppos.net>
|
||||
|
||||
require_relative "public_suffix/domain"
|
||||
require_relative "public_suffix/version"
|
||||
require_relative "public_suffix/errors"
|
||||
require_relative "public_suffix/rule"
|
||||
require_relative "public_suffix/list"
|
||||
|
||||
# PublicSuffix is a Ruby domain name parser based on the Public Suffix List.
|
||||
#
|
||||
# The [Public Suffix List](https://publicsuffix.org) is a cross-vendor initiative
|
||||
# to provide an accurate list of domain name suffixes.
|
||||
#
|
||||
# The Public Suffix List is an initiative of the Mozilla Project,
|
||||
# but is maintained as a community resource. It is available for use in any software,
|
||||
# but was originally created to meet the needs of browser manufacturers.
|
||||
module PublicSuffix
|
||||
|
||||
DOT = "."
|
||||
BANG = "!"
|
||||
STAR = "*"
|
||||
|
||||
# Parses +name+ and returns the {PublicSuffix::Domain} instance.
|
||||
#
|
||||
# @example Parse a valid domain
|
||||
# PublicSuffix.parse("google.com")
|
||||
# # => #<PublicSuffix::Domain:0x007fec2e51e588 @sld="google", @tld="com", @trd=nil>
|
||||
#
|
||||
# @example Parse a valid subdomain
|
||||
# PublicSuffix.parse("www.google.com")
|
||||
# # => #<PublicSuffix::Domain:0x007fec276d4cf8 @sld="google", @tld="com", @trd="www">
|
||||
#
|
||||
# @example Parse a fully qualified domain
|
||||
# PublicSuffix.parse("google.com.")
|
||||
# # => #<PublicSuffix::Domain:0x007fec257caf38 @sld="google", @tld="com", @trd=nil>
|
||||
#
|
||||
# @example Parse a fully qualified domain (subdomain)
|
||||
# PublicSuffix.parse("www.google.com.")
|
||||
# # => #<PublicSuffix::Domain:0x007fec27b6bca8 @sld="google", @tld="com", @trd="www">
|
||||
#
|
||||
# @example Parse an invalid (unlisted) domain
|
||||
# PublicSuffix.parse("x.yz")
|
||||
# # => #<PublicSuffix::Domain:0x007fec2f49bec0 @sld="x", @tld="yz", @trd=nil>
|
||||
#
|
||||
# @example Parse an invalid (unlisted) domain with strict checking (without applying the default * rule)
|
||||
# PublicSuffix.parse("x.yz", default_rule: nil)
|
||||
# # => PublicSuffix::DomainInvalid: `x.yz` is not a valid domain
|
||||
#
|
||||
# @example Parse an URL (not supported, only domains)
|
||||
# PublicSuffix.parse("http://www.google.com")
|
||||
# # => PublicSuffix::DomainInvalid: http://www.google.com is not expected to contain a scheme
|
||||
#
|
||||
#
|
||||
# @param [String, #to_s] name The domain name or fully qualified domain name to parse.
|
||||
# @param [PublicSuffix::List] list The rule list to search, defaults to the default {PublicSuffix::List}
|
||||
# @param [Boolean] ignore_private
|
||||
# @return [PublicSuffix::Domain]
|
||||
#
|
||||
# @raise [PublicSuffix::DomainInvalid]
|
||||
# If domain is not a valid domain.
|
||||
# @raise [PublicSuffix::DomainNotAllowed]
|
||||
# If a rule for +domain+ is found, but the rule doesn't allow +domain+.
|
||||
def self.parse(name, list: List.default, default_rule: list.default_rule, ignore_private: false)
|
||||
what = normalize(name)
|
||||
raise what if what.is_a?(DomainInvalid)
|
||||
|
||||
rule = list.find(what, default: default_rule, ignore_private: ignore_private)
|
||||
|
||||
# rubocop:disable Style/IfUnlessModifier
|
||||
if rule.nil?
|
||||
raise DomainInvalid, "`#{what}` is not a valid domain"
|
||||
end
|
||||
if rule.decompose(what).last.nil?
|
||||
raise DomainNotAllowed, "`#{what}` is not allowed according to Registry policy"
|
||||
end
|
||||
|
||||
# rubocop:enable Style/IfUnlessModifier
|
||||
|
||||
decompose(what, rule)
|
||||
end
|
||||
|
||||
# Checks whether +domain+ is assigned and allowed, without actually parsing it.
|
||||
#
|
||||
# This method doesn't care whether domain is a domain or subdomain.
|
||||
# The validation is performed using the default {PublicSuffix::List}.
|
||||
#
|
||||
# @example Validate a valid domain
|
||||
# PublicSuffix.valid?("example.com")
|
||||
# # => true
|
||||
#
|
||||
# @example Validate a valid subdomain
|
||||
# PublicSuffix.valid?("www.example.com")
|
||||
# # => true
|
||||
#
|
||||
# @example Validate a not-listed domain
|
||||
# PublicSuffix.valid?("example.tldnotlisted")
|
||||
# # => true
|
||||
#
|
||||
# @example Validate a not-listed domain with strict checking (without applying the default * rule)
|
||||
# PublicSuffix.valid?("example.tldnotlisted")
|
||||
# # => true
|
||||
# PublicSuffix.valid?("example.tldnotlisted", default_rule: nil)
|
||||
# # => false
|
||||
#
|
||||
# @example Validate a fully qualified domain
|
||||
# PublicSuffix.valid?("google.com.")
|
||||
# # => true
|
||||
# PublicSuffix.valid?("www.google.com.")
|
||||
# # => true
|
||||
#
|
||||
# @example Check an URL (which is not a valid domain)
|
||||
# PublicSuffix.valid?("http://www.example.com")
|
||||
# # => false
|
||||
#
|
||||
#
|
||||
# @param [String, #to_s] name The domain name or fully qualified domain name to validate.
|
||||
# @param [Boolean] ignore_private
|
||||
# @return [Boolean]
|
||||
def self.valid?(name, list: List.default, default_rule: list.default_rule, ignore_private: false)
|
||||
what = normalize(name)
|
||||
return false if what.is_a?(DomainInvalid)
|
||||
|
||||
rule = list.find(what, default: default_rule, ignore_private: ignore_private)
|
||||
|
||||
!rule.nil? && !rule.decompose(what).last.nil?
|
||||
end
|
||||
|
||||
# Attempt to parse the name and returns the domain, if valid.
|
||||
#
|
||||
# This method doesn't raise. Instead, it returns nil if the domain is not valid for whatever reason.
|
||||
#
|
||||
# @param [String, #to_s] name The domain name or fully qualified domain name to parse.
|
||||
# @param [PublicSuffix::List] list The rule list to search, defaults to the default {PublicSuffix::List}
|
||||
# @param [Boolean] ignore_private
|
||||
# @return [String]
|
||||
def self.domain(name, **options)
|
||||
parse(name, **options).domain
|
||||
rescue PublicSuffix::Error
|
||||
nil
|
||||
end
|
||||
|
||||
|
||||
# private
|
||||
|
||||
def self.decompose(name, rule)
|
||||
left, right = rule.decompose(name)
|
||||
|
||||
parts = left.split(DOT)
|
||||
# If we have 0 parts left, there is just a tld and no domain or subdomain
|
||||
# If we have 1 part left, there is just a tld, domain and not subdomain
|
||||
# If we have 2 parts left, the last part is the domain, the other parts (combined) are the subdomain
|
||||
tld = right
|
||||
sld = parts.empty? ? nil : parts.pop
|
||||
trd = parts.empty? ? nil : parts.join(DOT)
|
||||
|
||||
Domain.new(tld, sld, trd)
|
||||
end
|
||||
|
||||
# Pretend we know how to deal with user input.
|
||||
def self.normalize(name)
|
||||
name = name.to_s.dup
|
||||
name.strip!
|
||||
name.chomp!(DOT)
|
||||
name.downcase!
|
||||
|
||||
return DomainInvalid.new("Name is blank") if name.empty?
|
||||
return DomainInvalid.new("Name starts with a dot") if name.start_with?(DOT)
|
||||
return DomainInvalid.new("%s is not expected to contain a scheme" % name) if name.include?("://")
|
||||
|
||||
name
|
||||
end
|
||||
|
||||
end
|
||||
235
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/public_suffix-4.0.6/lib/public_suffix/domain.rb
vendored
Normal file
235
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/public_suffix-4.0.6/lib/public_suffix/domain.rb
vendored
Normal file
@ -0,0 +1,235 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# = Public Suffix
|
||||
#
|
||||
# Domain name parser based on the Public Suffix List.
|
||||
#
|
||||
# Copyright (c) 2009-2020 Simone Carletti <weppos@weppos.net>
|
||||
|
||||
module PublicSuffix
|
||||
|
||||
# Domain represents a domain name, composed by a TLD, SLD and TRD.
|
||||
class Domain
|
||||
|
||||
# Splits a string into the labels, that is the dot-separated parts.
|
||||
#
|
||||
# The input is not validated, but it is assumed to be a valid domain name.
|
||||
#
|
||||
# @example
|
||||
#
|
||||
# name_to_labels('example.com')
|
||||
# # => ['example', 'com']
|
||||
#
|
||||
# name_to_labels('example.co.uk')
|
||||
# # => ['example', 'co', 'uk']
|
||||
#
|
||||
# @param name [String, #to_s] The domain name to split.
|
||||
# @return [Array<String>]
|
||||
def self.name_to_labels(name)
|
||||
name.to_s.split(DOT)
|
||||
end
|
||||
|
||||
|
||||
attr_reader :tld, :sld, :trd
|
||||
|
||||
# Creates and returns a new {PublicSuffix::Domain} instance.
|
||||
#
|
||||
# @overload initialize(tld)
|
||||
# Initializes with a +tld+.
|
||||
# @param [String] tld The TLD (extension)
|
||||
# @overload initialize(tld, sld)
|
||||
# Initializes with a +tld+ and +sld+.
|
||||
# @param [String] tld The TLD (extension)
|
||||
# @param [String] sld The TRD (domain)
|
||||
# @overload initialize(tld, sld, trd)
|
||||
# Initializes with a +tld+, +sld+ and +trd+.
|
||||
# @param [String] tld The TLD (extension)
|
||||
# @param [String] sld The SLD (domain)
|
||||
# @param [String] trd The TRD (subdomain)
|
||||
#
|
||||
# @yield [self] Yields on self.
|
||||
# @yieldparam [PublicSuffix::Domain] self The newly creates instance
|
||||
#
|
||||
# @example Initialize with a TLD
|
||||
# PublicSuffix::Domain.new("com")
|
||||
# # => #<PublicSuffix::Domain @tld="com">
|
||||
#
|
||||
# @example Initialize with a TLD and SLD
|
||||
# PublicSuffix::Domain.new("com", "example")
|
||||
# # => #<PublicSuffix::Domain @tld="com", @trd=nil>
|
||||
#
|
||||
# @example Initialize with a TLD, SLD and TRD
|
||||
# PublicSuffix::Domain.new("com", "example", "wwww")
|
||||
# # => #<PublicSuffix::Domain @tld="com", @trd=nil, @sld="example">
|
||||
#
|
||||
def initialize(*args)
|
||||
@tld, @sld, @trd = args
|
||||
yield(self) if block_given?
|
||||
end
|
||||
|
||||
# Returns a string representation of this object.
|
||||
#
|
||||
# @return [String]
|
||||
def to_s
|
||||
name
|
||||
end
|
||||
|
||||
# Returns an array containing the domain parts.
|
||||
#
|
||||
# @return [Array<String, nil>]
|
||||
#
|
||||
# @example
|
||||
#
|
||||
# PublicSuffix::Domain.new("google.com").to_a
|
||||
# # => [nil, "google", "com"]
|
||||
#
|
||||
# PublicSuffix::Domain.new("www.google.com").to_a
|
||||
# # => [nil, "google", "com"]
|
||||
#
|
||||
def to_a
|
||||
[@trd, @sld, @tld]
|
||||
end
|
||||
|
||||
# Returns the full domain name.
|
||||
#
|
||||
# @return [String]
|
||||
#
|
||||
# @example Gets the domain name of a domain
|
||||
# PublicSuffix::Domain.new("com", "google").name
|
||||
# # => "google.com"
|
||||
#
|
||||
# @example Gets the domain name of a subdomain
|
||||
# PublicSuffix::Domain.new("com", "google", "www").name
|
||||
# # => "www.google.com"
|
||||
#
|
||||
def name
|
||||
[@trd, @sld, @tld].compact.join(DOT)
|
||||
end
|
||||
|
||||
# Returns a domain-like representation of this object
|
||||
# if the object is a {#domain?}, <tt>nil</tt> otherwise.
|
||||
#
|
||||
# PublicSuffix::Domain.new("com").domain
|
||||
# # => nil
|
||||
#
|
||||
# PublicSuffix::Domain.new("com", "google").domain
|
||||
# # => "google.com"
|
||||
#
|
||||
# PublicSuffix::Domain.new("com", "google", "www").domain
|
||||
# # => "www.google.com"
|
||||
#
|
||||
# This method doesn't validate the input. It handles the domain
|
||||
# as a valid domain name and simply applies the necessary transformations.
|
||||
#
|
||||
# This method returns a FQD, not just the domain part.
|
||||
# To get the domain part, use <tt>#sld</tt> (aka second level domain).
|
||||
#
|
||||
# PublicSuffix::Domain.new("com", "google", "www").domain
|
||||
# # => "google.com"
|
||||
#
|
||||
# PublicSuffix::Domain.new("com", "google", "www").sld
|
||||
# # => "google"
|
||||
#
|
||||
# @see #domain?
|
||||
# @see #subdomain
|
||||
#
|
||||
# @return [String]
|
||||
def domain
|
||||
[@sld, @tld].join(DOT) if domain?
|
||||
end
|
||||
|
||||
# Returns a subdomain-like representation of this object
|
||||
# if the object is a {#subdomain?}, <tt>nil</tt> otherwise.
|
||||
#
|
||||
# PublicSuffix::Domain.new("com").subdomain
|
||||
# # => nil
|
||||
#
|
||||
# PublicSuffix::Domain.new("com", "google").subdomain
|
||||
# # => nil
|
||||
#
|
||||
# PublicSuffix::Domain.new("com", "google", "www").subdomain
|
||||
# # => "www.google.com"
|
||||
#
|
||||
# This method doesn't validate the input. It handles the domain
|
||||
# as a valid domain name and simply applies the necessary transformations.
|
||||
#
|
||||
# This method returns a FQD, not just the subdomain part.
|
||||
# To get the subdomain part, use <tt>#trd</tt> (aka third level domain).
|
||||
#
|
||||
# PublicSuffix::Domain.new("com", "google", "www").subdomain
|
||||
# # => "www.google.com"
|
||||
#
|
||||
# PublicSuffix::Domain.new("com", "google", "www").trd
|
||||
# # => "www"
|
||||
#
|
||||
# @see #subdomain?
|
||||
# @see #domain
|
||||
#
|
||||
# @return [String]
|
||||
def subdomain
|
||||
[@trd, @sld, @tld].join(DOT) if subdomain?
|
||||
end
|
||||
|
||||
# Checks whether <tt>self</tt> looks like a domain.
|
||||
#
|
||||
# This method doesn't actually validate the domain.
|
||||
# It only checks whether the instance contains
|
||||
# a value for the {#tld} and {#sld} attributes.
|
||||
#
|
||||
# @example
|
||||
#
|
||||
# PublicSuffix::Domain.new("com").domain?
|
||||
# # => false
|
||||
#
|
||||
# PublicSuffix::Domain.new("com", "google").domain?
|
||||
# # => true
|
||||
#
|
||||
# PublicSuffix::Domain.new("com", "google", "www").domain?
|
||||
# # => true
|
||||
#
|
||||
# # This is an invalid domain, but returns true
|
||||
# # because this method doesn't validate the content.
|
||||
# PublicSuffix::Domain.new("com", nil).domain?
|
||||
# # => true
|
||||
#
|
||||
# @see #subdomain?
|
||||
#
|
||||
# @return [Boolean]
|
||||
def domain?
|
||||
!(@tld.nil? || @sld.nil?)
|
||||
end
|
||||
|
||||
# Checks whether <tt>self</tt> looks like a subdomain.
|
||||
#
|
||||
# This method doesn't actually validate the subdomain.
|
||||
# It only checks whether the instance contains
|
||||
# a value for the {#tld}, {#sld} and {#trd} attributes.
|
||||
# If you also want to validate the domain,
|
||||
# use {#valid_subdomain?} instead.
|
||||
#
|
||||
# @example
|
||||
#
|
||||
# PublicSuffix::Domain.new("com").subdomain?
|
||||
# # => false
|
||||
#
|
||||
# PublicSuffix::Domain.new("com", "google").subdomain?
|
||||
# # => false
|
||||
#
|
||||
# PublicSuffix::Domain.new("com", "google", "www").subdomain?
|
||||
# # => true
|
||||
#
|
||||
# # This is an invalid domain, but returns true
|
||||
# # because this method doesn't validate the content.
|
||||
# PublicSuffix::Domain.new("com", "example", nil).subdomain?
|
||||
# # => true
|
||||
#
|
||||
# @see #domain?
|
||||
#
|
||||
# @return [Boolean]
|
||||
def subdomain?
|
||||
!(@tld.nil? || @sld.nil? || @trd.nil?)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
41
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/public_suffix-4.0.6/lib/public_suffix/errors.rb
vendored
Normal file
41
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/public_suffix-4.0.6/lib/public_suffix/errors.rb
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# = Public Suffix
|
||||
#
|
||||
# Domain name parser based on the Public Suffix List.
|
||||
#
|
||||
# Copyright (c) 2009-2020 Simone Carletti <weppos@weppos.net>
|
||||
|
||||
module PublicSuffix
|
||||
|
||||
class Error < StandardError
|
||||
end
|
||||
|
||||
# Raised when trying to parse an invalid name.
|
||||
# A name is considered invalid when no rule is found in the definition list.
|
||||
#
|
||||
# @example
|
||||
#
|
||||
# PublicSuffix.parse("nic.test")
|
||||
# # => PublicSuffix::DomainInvalid
|
||||
#
|
||||
# PublicSuffix.parse("http://www.nic.it")
|
||||
# # => PublicSuffix::DomainInvalid
|
||||
#
|
||||
class DomainInvalid < Error
|
||||
end
|
||||
|
||||
# Raised when trying to parse a name that matches a suffix.
|
||||
#
|
||||
# @example
|
||||
#
|
||||
# PublicSuffix.parse("nic.do")
|
||||
# # => PublicSuffix::DomainNotAllowed
|
||||
#
|
||||
# PublicSuffix.parse("www.nic.do")
|
||||
# # => PublicSuffix::Domain
|
||||
#
|
||||
class DomainNotAllowed < DomainInvalid
|
||||
end
|
||||
|
||||
end
|
||||
247
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/public_suffix-4.0.6/lib/public_suffix/list.rb
vendored
Normal file
247
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/public_suffix-4.0.6/lib/public_suffix/list.rb
vendored
Normal file
@ -0,0 +1,247 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# = Public Suffix
|
||||
#
|
||||
# Domain name parser based on the Public Suffix List.
|
||||
#
|
||||
# Copyright (c) 2009-2020 Simone Carletti <weppos@weppos.net>
|
||||
|
||||
module PublicSuffix
|
||||
|
||||
# A {PublicSuffix::List} is a collection of one
|
||||
# or more {PublicSuffix::Rule}.
|
||||
#
|
||||
# Given a {PublicSuffix::List},
|
||||
# you can add or remove {PublicSuffix::Rule},
|
||||
# iterate all items in the list or search for the first rule
|
||||
# which matches a specific domain name.
|
||||
#
|
||||
# # Create a new list
|
||||
# list = PublicSuffix::List.new
|
||||
#
|
||||
# # Push two rules to the list
|
||||
# list << PublicSuffix::Rule.factory("it")
|
||||
# list << PublicSuffix::Rule.factory("com")
|
||||
#
|
||||
# # Get the size of the list
|
||||
# list.size
|
||||
# # => 2
|
||||
#
|
||||
# # Search for the rule matching given domain
|
||||
# list.find("example.com")
|
||||
# # => #<PublicSuffix::Rule::Normal>
|
||||
# list.find("example.org")
|
||||
# # => nil
|
||||
#
|
||||
# You can create as many {PublicSuffix::List} you want.
|
||||
# The {PublicSuffix::List.default} rule list is used
|
||||
# to tokenize and validate a domain.
|
||||
#
|
||||
class List
|
||||
|
||||
DEFAULT_LIST_PATH = File.expand_path("../../data/list.txt", __dir__)
|
||||
|
||||
# Gets the default rule list.
|
||||
#
|
||||
# Initializes a new {PublicSuffix::List} parsing the content
|
||||
# of {PublicSuffix::List.default_list_content}, if required.
|
||||
#
|
||||
# @return [PublicSuffix::List]
|
||||
def self.default(**options)
|
||||
@default ||= parse(File.read(DEFAULT_LIST_PATH), **options)
|
||||
end
|
||||
|
||||
# Sets the default rule list to +value+.
|
||||
#
|
||||
# @param value [PublicSuffix::List] the new list
|
||||
# @return [PublicSuffix::List]
|
||||
def self.default=(value)
|
||||
@default = value
|
||||
end
|
||||
|
||||
# Parse given +input+ treating the content as Public Suffix List.
|
||||
#
|
||||
# See http://publicsuffix.org/format/ for more details about input format.
|
||||
#
|
||||
# @param string [#each_line] the list to parse
|
||||
# @param private_domains [Boolean] whether to ignore the private domains section
|
||||
# @return [PublicSuffix::List]
|
||||
def self.parse(input, private_domains: true)
|
||||
comment_token = "//"
|
||||
private_token = "===BEGIN PRIVATE DOMAINS==="
|
||||
section = nil # 1 == ICANN, 2 == PRIVATE
|
||||
|
||||
new do |list|
|
||||
input.each_line do |line|
|
||||
line.strip!
|
||||
case # rubocop:disable Style/EmptyCaseCondition
|
||||
|
||||
# skip blank lines
|
||||
when line.empty?
|
||||
next
|
||||
|
||||
# include private domains or stop scanner
|
||||
when line.include?(private_token)
|
||||
break if !private_domains
|
||||
|
||||
section = 2
|
||||
|
||||
# skip comments
|
||||
when line.start_with?(comment_token)
|
||||
next
|
||||
|
||||
else
|
||||
list.add(Rule.factory(line, private: section == 2))
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# Initializes an empty {PublicSuffix::List}.
|
||||
#
|
||||
# @yield [self] Yields on self.
|
||||
# @yieldparam [PublicSuffix::List] self The newly created instance.
|
||||
def initialize
|
||||
@rules = {}
|
||||
yield(self) if block_given?
|
||||
end
|
||||
|
||||
|
||||
# Checks whether two lists are equal.
|
||||
#
|
||||
# List <tt>one</tt> is equal to <tt>two</tt>, if <tt>two</tt> is an instance of
|
||||
# {PublicSuffix::List} and each +PublicSuffix::Rule::*+
|
||||
# in list <tt>one</tt> is available in list <tt>two</tt>, in the same order.
|
||||
#
|
||||
# @param other [PublicSuffix::List] the List to compare
|
||||
# @return [Boolean]
|
||||
def ==(other)
|
||||
return false unless other.is_a?(List)
|
||||
|
||||
equal?(other) || @rules == other.rules
|
||||
end
|
||||
alias eql? ==
|
||||
|
||||
# Iterates each rule in the list.
|
||||
def each(&block)
|
||||
Enumerator.new do |y|
|
||||
@rules.each do |key, node|
|
||||
y << entry_to_rule(node, key)
|
||||
end
|
||||
end.each(&block)
|
||||
end
|
||||
|
||||
|
||||
# Adds the given object to the list and optionally refreshes the rule index.
|
||||
#
|
||||
# @param rule [PublicSuffix::Rule::*] the rule to add to the list
|
||||
# @return [self]
|
||||
def add(rule)
|
||||
@rules[rule.value] = rule_to_entry(rule)
|
||||
self
|
||||
end
|
||||
alias << add
|
||||
|
||||
# Gets the number of rules in the list.
|
||||
#
|
||||
# @return [Integer]
|
||||
def size
|
||||
@rules.size
|
||||
end
|
||||
|
||||
# Checks whether the list is empty.
|
||||
#
|
||||
# @return [Boolean]
|
||||
def empty?
|
||||
@rules.empty?
|
||||
end
|
||||
|
||||
# Removes all rules.
|
||||
#
|
||||
# @return [self]
|
||||
def clear
|
||||
@rules.clear
|
||||
self
|
||||
end
|
||||
|
||||
# Finds and returns the rule corresponding to the longest public suffix for the hostname.
|
||||
#
|
||||
# @param name [#to_s] the hostname
|
||||
# @param default [PublicSuffix::Rule::*] the default rule to return in case no rule matches
|
||||
# @return [PublicSuffix::Rule::*]
|
||||
def find(name, default: default_rule, **options)
|
||||
rule = select(name, **options).inject do |l, r|
|
||||
return r if r.class == Rule::Exception
|
||||
|
||||
l.length > r.length ? l : r
|
||||
end
|
||||
rule || default
|
||||
end
|
||||
|
||||
# Selects all the rules matching given hostame.
|
||||
#
|
||||
# If `ignore_private` is set to true, the algorithm will skip the rules that are flagged as
|
||||
# private domain. Note that the rules will still be part of the loop.
|
||||
# If you frequently need to access lists ignoring the private domains,
|
||||
# you should create a list that doesn't include these domains setting the
|
||||
# `private_domains: false` option when calling {.parse}.
|
||||
#
|
||||
# Note that this method is currently private, as you should not rely on it. Instead,
|
||||
# the public interface is {#find}. The current internal algorithm allows to return all
|
||||
# matching rules, but different data structures may not be able to do it, and instead would
|
||||
# return only the match. For this reason, you should rely on {#find}.
|
||||
#
|
||||
# @param name [#to_s] the hostname
|
||||
# @param ignore_private [Boolean]
|
||||
# @return [Array<PublicSuffix::Rule::*>]
|
||||
def select(name, ignore_private: false)
|
||||
name = name.to_s
|
||||
|
||||
parts = name.split(DOT).reverse!
|
||||
index = 0
|
||||
query = parts[index]
|
||||
rules = []
|
||||
|
||||
loop do
|
||||
match = @rules[query]
|
||||
rules << entry_to_rule(match, query) if !match.nil? && (ignore_private == false || match.private == false)
|
||||
|
||||
index += 1
|
||||
break if index >= parts.size
|
||||
|
||||
query = parts[index] + DOT + query
|
||||
end
|
||||
|
||||
rules
|
||||
end
|
||||
private :select
|
||||
|
||||
# Gets the default rule.
|
||||
#
|
||||
# @see PublicSuffix::Rule.default_rule
|
||||
#
|
||||
# @return [PublicSuffix::Rule::*]
|
||||
def default_rule
|
||||
PublicSuffix::Rule.default
|
||||
end
|
||||
|
||||
|
||||
protected
|
||||
|
||||
attr_reader :rules
|
||||
|
||||
|
||||
private
|
||||
|
||||
def entry_to_rule(entry, value)
|
||||
entry.type.new(value: value, length: entry.length, private: entry.private)
|
||||
end
|
||||
|
||||
def rule_to_entry(rule)
|
||||
Rule::Entry.new(rule.class, rule.length, rule.private)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
350
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/public_suffix-4.0.6/lib/public_suffix/rule.rb
vendored
Normal file
350
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/public_suffix-4.0.6/lib/public_suffix/rule.rb
vendored
Normal file
@ -0,0 +1,350 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# = Public Suffix
|
||||
#
|
||||
# Domain name parser based on the Public Suffix List.
|
||||
#
|
||||
# Copyright (c) 2009-2020 Simone Carletti <weppos@weppos.net>
|
||||
|
||||
module PublicSuffix
|
||||
|
||||
# A Rule is a special object which holds a single definition
|
||||
# of the Public Suffix List.
|
||||
#
|
||||
# There are 3 types of rules, each one represented by a specific
|
||||
# subclass within the +PublicSuffix::Rule+ namespace.
|
||||
#
|
||||
# To create a new Rule, use the {PublicSuffix::Rule#factory} method.
|
||||
#
|
||||
# PublicSuffix::Rule.factory("ar")
|
||||
# # => #<PublicSuffix::Rule::Normal>
|
||||
#
|
||||
module Rule
|
||||
|
||||
# @api internal
|
||||
Entry = Struct.new(:type, :length, :private) # rubocop:disable Lint/StructNewOverride
|
||||
|
||||
# = Abstract rule class
|
||||
#
|
||||
# This represent the base class for a Rule definition
|
||||
# in the {Public Suffix List}[https://publicsuffix.org].
|
||||
#
|
||||
# This is intended to be an Abstract class
|
||||
# and you shouldn't create a direct instance. The only purpose
|
||||
# of this class is to expose a common interface
|
||||
# for all the available subclasses.
|
||||
#
|
||||
# * {PublicSuffix::Rule::Normal}
|
||||
# * {PublicSuffix::Rule::Exception}
|
||||
# * {PublicSuffix::Rule::Wildcard}
|
||||
#
|
||||
# ## Properties
|
||||
#
|
||||
# A rule is composed by 4 properties:
|
||||
#
|
||||
# value - A normalized version of the rule name.
|
||||
# The normalization process depends on rule tpe.
|
||||
#
|
||||
# Here's an example
|
||||
#
|
||||
# PublicSuffix::Rule.factory("*.google.com")
|
||||
# #<PublicSuffix::Rule::Wildcard:0x1015c14b0
|
||||
# @value="google.com"
|
||||
# >
|
||||
#
|
||||
# ## Rule Creation
|
||||
#
|
||||
# The best way to create a new rule is passing the rule name
|
||||
# to the <tt>PublicSuffix::Rule.factory</tt> method.
|
||||
#
|
||||
# PublicSuffix::Rule.factory("com")
|
||||
# # => PublicSuffix::Rule::Normal
|
||||
#
|
||||
# PublicSuffix::Rule.factory("*.com")
|
||||
# # => PublicSuffix::Rule::Wildcard
|
||||
#
|
||||
# This method will detect the rule type and create an instance
|
||||
# from the proper rule class.
|
||||
#
|
||||
# ## Rule Usage
|
||||
#
|
||||
# A rule describes the composition of a domain name and explains how to tokenize
|
||||
# the name into tld, sld and trd.
|
||||
#
|
||||
# To use a rule, you first need to be sure the name you want to tokenize
|
||||
# can be handled by the current rule.
|
||||
# You can use the <tt>#match?</tt> method.
|
||||
#
|
||||
# rule = PublicSuffix::Rule.factory("com")
|
||||
#
|
||||
# rule.match?("google.com")
|
||||
# # => true
|
||||
#
|
||||
# rule.match?("google.com")
|
||||
# # => false
|
||||
#
|
||||
# Rule order is significant. A name can match more than one rule.
|
||||
# See the {Public Suffix Documentation}[http://publicsuffix.org/format/]
|
||||
# to learn more about rule priority.
|
||||
#
|
||||
# When you have the right rule, you can use it to tokenize the domain name.
|
||||
#
|
||||
# rule = PublicSuffix::Rule.factory("com")
|
||||
#
|
||||
# rule.decompose("google.com")
|
||||
# # => ["google", "com"]
|
||||
#
|
||||
# rule.decompose("www.google.com")
|
||||
# # => ["www.google", "com"]
|
||||
#
|
||||
# @abstract
|
||||
#
|
||||
class Base
|
||||
|
||||
# @return [String] the rule definition
|
||||
attr_reader :value
|
||||
|
||||
# @return [String] the length of the rule
|
||||
attr_reader :length
|
||||
|
||||
# @return [Boolean] true if the rule is a private domain
|
||||
attr_reader :private
|
||||
|
||||
|
||||
# Initializes a new rule from the content.
|
||||
#
|
||||
# @param content [String] the content of the rule
|
||||
# @param private [Boolean]
|
||||
def self.build(content, private: false)
|
||||
new(value: content, private: private)
|
||||
end
|
||||
|
||||
# Initializes a new rule.
|
||||
#
|
||||
# @param value [String]
|
||||
# @param private [Boolean]
|
||||
def initialize(value:, length: nil, private: false)
|
||||
@value = value.to_s
|
||||
@length = length || @value.count(DOT) + 1
|
||||
@private = private
|
||||
end
|
||||
|
||||
# Checks whether this rule is equal to <tt>other</tt>.
|
||||
#
|
||||
# @param [PublicSuffix::Rule::*] other The rule to compare
|
||||
# @return [Boolean]
|
||||
# Returns true if this rule and other are instances of the same class
|
||||
# and has the same value, false otherwise.
|
||||
def ==(other)
|
||||
equal?(other) || (self.class == other.class && value == other.value)
|
||||
end
|
||||
alias eql? ==
|
||||
|
||||
# Checks if this rule matches +name+.
|
||||
#
|
||||
# A domain name is said to match a rule if and only if
|
||||
# all of the following conditions are met:
|
||||
#
|
||||
# - When the domain and rule are split into corresponding labels,
|
||||
# that the domain contains as many or more labels than the rule.
|
||||
# - Beginning with the right-most labels of both the domain and the rule,
|
||||
# and continuing for all labels in the rule, one finds that for every pair,
|
||||
# either they are identical, or that the label from the rule is "*".
|
||||
#
|
||||
# @see https://publicsuffix.org/list/
|
||||
#
|
||||
# @example
|
||||
# PublicSuffix::Rule.factory("com").match?("example.com")
|
||||
# # => true
|
||||
# PublicSuffix::Rule.factory("com").match?("example.net")
|
||||
# # => false
|
||||
#
|
||||
# @param name [String] the domain name to check
|
||||
# @return [Boolean]
|
||||
def match?(name)
|
||||
# Note: it works because of the assumption there are no
|
||||
# rules like foo.*.com. If the assumption is incorrect,
|
||||
# we need to properly walk the input and skip parts according
|
||||
# to wildcard component.
|
||||
diff = name.chomp(value)
|
||||
diff.empty? || diff.end_with?(DOT)
|
||||
end
|
||||
|
||||
# @abstract
|
||||
def parts
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
# @abstract
|
||||
# @param [String, #to_s] name The domain name to decompose
|
||||
# @return [Array<String, nil>]
|
||||
def decompose(*)
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Normal represents a standard rule (e.g. com).
|
||||
class Normal < Base
|
||||
|
||||
# Gets the original rule definition.
|
||||
#
|
||||
# @return [String] The rule definition.
|
||||
def rule
|
||||
value
|
||||
end
|
||||
|
||||
# Decomposes the domain name according to rule properties.
|
||||
#
|
||||
# @param [String, #to_s] name The domain name to decompose
|
||||
# @return [Array<String>] The array with [trd + sld, tld].
|
||||
def decompose(domain)
|
||||
suffix = parts.join('\.')
|
||||
matches = domain.to_s.match(/^(.*)\.(#{suffix})$/)
|
||||
matches ? matches[1..2] : [nil, nil]
|
||||
end
|
||||
|
||||
# dot-split rule value and returns all rule parts
|
||||
# in the order they appear in the value.
|
||||
#
|
||||
# @return [Array<String>]
|
||||
def parts
|
||||
@value.split(DOT)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Wildcard represents a wildcard rule (e.g. *.co.uk).
|
||||
class Wildcard < Base
|
||||
|
||||
# Initializes a new rule from the content.
|
||||
#
|
||||
# @param content [String] the content of the rule
|
||||
# @param private [Boolean]
|
||||
def self.build(content, private: false)
|
||||
new(value: content.to_s[2..-1], private: private)
|
||||
end
|
||||
|
||||
# Initializes a new rule.
|
||||
#
|
||||
# @param value [String]
|
||||
# @param private [Boolean]
|
||||
def initialize(value:, length: nil, private: false)
|
||||
super(value: value, length: length, private: private)
|
||||
length or @length += 1 # * counts as 1
|
||||
end
|
||||
|
||||
# Gets the original rule definition.
|
||||
#
|
||||
# @return [String] The rule definition.
|
||||
def rule
|
||||
value == "" ? STAR : STAR + DOT + value
|
||||
end
|
||||
|
||||
# Decomposes the domain name according to rule properties.
|
||||
#
|
||||
# @param [String, #to_s] name The domain name to decompose
|
||||
# @return [Array<String>] The array with [trd + sld, tld].
|
||||
def decompose(domain)
|
||||
suffix = ([".*?"] + parts).join('\.')
|
||||
matches = domain.to_s.match(/^(.*)\.(#{suffix})$/)
|
||||
matches ? matches[1..2] : [nil, nil]
|
||||
end
|
||||
|
||||
# dot-split rule value and returns all rule parts
|
||||
# in the order they appear in the value.
|
||||
#
|
||||
# @return [Array<String>]
|
||||
def parts
|
||||
@value.split(DOT)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Exception represents an exception rule (e.g. !parliament.uk).
|
||||
class Exception < Base
|
||||
|
||||
# Initializes a new rule from the content.
|
||||
#
|
||||
# @param content [String] the content of the rule
|
||||
# @param private [Boolean]
|
||||
def self.build(content, private: false)
|
||||
new(value: content.to_s[1..-1], private: private)
|
||||
end
|
||||
|
||||
# Gets the original rule definition.
|
||||
#
|
||||
# @return [String] The rule definition.
|
||||
def rule
|
||||
BANG + value
|
||||
end
|
||||
|
||||
# Decomposes the domain name according to rule properties.
|
||||
#
|
||||
# @param [String, #to_s] name The domain name to decompose
|
||||
# @return [Array<String>] The array with [trd + sld, tld].
|
||||
def decompose(domain)
|
||||
suffix = parts.join('\.')
|
||||
matches = domain.to_s.match(/^(.*)\.(#{suffix})$/)
|
||||
matches ? matches[1..2] : [nil, nil]
|
||||
end
|
||||
|
||||
# dot-split rule value and returns all rule parts
|
||||
# in the order they appear in the value.
|
||||
# The leftmost label is not considered a label.
|
||||
#
|
||||
# See http://publicsuffix.org/format/:
|
||||
# If the prevailing rule is a exception rule,
|
||||
# modify it by removing the leftmost label.
|
||||
#
|
||||
# @return [Array<String>]
|
||||
def parts
|
||||
@value.split(DOT)[1..-1]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
# Takes the +name+ of the rule, detects the specific rule class
|
||||
# and creates a new instance of that class.
|
||||
# The +name+ becomes the rule +value+.
|
||||
#
|
||||
# @example Creates a Normal rule
|
||||
# PublicSuffix::Rule.factory("ar")
|
||||
# # => #<PublicSuffix::Rule::Normal>
|
||||
#
|
||||
# @example Creates a Wildcard rule
|
||||
# PublicSuffix::Rule.factory("*.ar")
|
||||
# # => #<PublicSuffix::Rule::Wildcard>
|
||||
#
|
||||
# @example Creates an Exception rule
|
||||
# PublicSuffix::Rule.factory("!congresodelalengua3.ar")
|
||||
# # => #<PublicSuffix::Rule::Exception>
|
||||
#
|
||||
# @param [String] content The rule content.
|
||||
# @return [PublicSuffix::Rule::*] A rule instance.
|
||||
def self.factory(content, private: false)
|
||||
case content.to_s[0, 1]
|
||||
when STAR
|
||||
Wildcard
|
||||
when BANG
|
||||
Exception
|
||||
else
|
||||
Normal
|
||||
end.build(content, private: private)
|
||||
end
|
||||
|
||||
# The default rule to use if no rule match.
|
||||
#
|
||||
# The default rule is "*". From https://publicsuffix.org/list/:
|
||||
#
|
||||
# > If no rules match, the prevailing rule is "*".
|
||||
#
|
||||
# @return [PublicSuffix::Rule::Wildcard] The default rule.
|
||||
def self.default
|
||||
factory(STAR)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
13
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/public_suffix-4.0.6/lib/public_suffix/version.rb
vendored
Normal file
13
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/public_suffix-4.0.6/lib/public_suffix/version.rb
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
#
|
||||
# = Public Suffix
|
||||
#
|
||||
# Domain name parser based on the Public Suffix List.
|
||||
#
|
||||
# Copyright (c) 2009-2020 Simone Carletti <weppos@weppos.net>
|
||||
|
||||
module PublicSuffix
|
||||
# The current library version.
|
||||
VERSION = "4.0.6"
|
||||
end
|
||||
266
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/net/ntlm.rb
vendored
Normal file
266
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/net/ntlm.rb
vendored
Normal file
@ -0,0 +1,266 @@
|
||||
# encoding: UTF-8
|
||||
#
|
||||
# = net/ntlm.rb
|
||||
#
|
||||
# An NTLM Authentication Library for Ruby
|
||||
#
|
||||
# This code is a derivative of "dbf2.rb" written by yrock
|
||||
# and Minero Aoki. You can find original code here:
|
||||
# http://jp.rubyist.net/magazine/?0013-CodeReview
|
||||
# -------------------------------------------------------------
|
||||
# Copyright (c) 2005,2006 yrock
|
||||
#
|
||||
#
|
||||
# 2006-02-11 refactored by Minero Aoki
|
||||
# -------------------------------------------------------------
|
||||
#
|
||||
# All protocol information used to write this code stems from
|
||||
# "The NTLM Authentication Protocol" by Eric Glass. The author
|
||||
# would thank to him for this tremendous work and making it
|
||||
# available on the net.
|
||||
# http://davenport.sourceforge.net/ntlm.html
|
||||
# -------------------------------------------------------------
|
||||
# Copyright (c) 2003 Eric Glass
|
||||
#
|
||||
# -------------------------------------------------------------
|
||||
#
|
||||
# The author also looked Mozilla-Firefox-1.0.7 source code,
|
||||
# namely, security/manager/ssl/src/nsNTLMAuthModule.cpp and
|
||||
# Jonathan Bastien-Filiatrault's libntlm-ruby.
|
||||
# "http://x2a.org/websvn/filedetails.php?
|
||||
# repname=libntlm-ruby&path=%2Ftrunk%2Fntlm.rb&sc=1"
|
||||
# The latter has a minor bug in its separate_keys function.
|
||||
# The third key has to begin from the 14th character of the
|
||||
# input string instead of 13th:)
|
||||
#--
|
||||
# $Id: ntlm.rb,v 1.1 2006/10/05 01:36:52 koheik Exp $
|
||||
#++
|
||||
|
||||
require 'base64'
|
||||
require 'openssl'
|
||||
require 'openssl/digest'
|
||||
require 'socket'
|
||||
|
||||
# Load Order is important here
|
||||
require 'net/ntlm/exceptions'
|
||||
require 'net/ntlm/field'
|
||||
require 'net/ntlm/int16_le'
|
||||
require 'net/ntlm/int32_le'
|
||||
require 'net/ntlm/int64_le'
|
||||
require 'net/ntlm/string'
|
||||
|
||||
require 'net/ntlm/field_set'
|
||||
require 'net/ntlm/blob'
|
||||
require 'net/ntlm/security_buffer'
|
||||
require 'net/ntlm/message'
|
||||
require 'net/ntlm/message/type0'
|
||||
require 'net/ntlm/message/type1'
|
||||
require 'net/ntlm/message/type2'
|
||||
require 'net/ntlm/message/type3'
|
||||
|
||||
require 'net/ntlm/encode_util'
|
||||
|
||||
require 'net/ntlm/client'
|
||||
require 'net/ntlm/channel_binding'
|
||||
require 'net/ntlm/target_info'
|
||||
|
||||
module Net
|
||||
module NTLM
|
||||
|
||||
LM_MAGIC = "KGS!@\#$%"
|
||||
TIME_OFFSET = 11644473600
|
||||
MAX64 = 0xffffffffffffffff
|
||||
|
||||
|
||||
class << self
|
||||
|
||||
# Valid format for LAN Manager hex digest portion: 32 hexadecimal characters.
|
||||
LAN_MANAGER_HEX_DIGEST_REGEXP = /[0-9a-f]{32}/i
|
||||
# Valid format for NT LAN Manager hex digest portion: 32 hexadecimal characters.
|
||||
NT_LAN_MANAGER_HEX_DIGEST_REGEXP = /[0-9a-f]{32}/i
|
||||
# Valid format for an NTLM hash composed of `'<LAN Manager hex digest>:<NT LAN Manager hex digest>'`.
|
||||
DATA_REGEXP = /\A#{LAN_MANAGER_HEX_DIGEST_REGEXP}:#{NT_LAN_MANAGER_HEX_DIGEST_REGEXP}\z/
|
||||
|
||||
# Takes a string and determines whether it is a valid NTLM Hash
|
||||
# @param [String] the string to validate
|
||||
# @return [Boolean] whether or not the string is a valid NTLM hash
|
||||
def is_ntlm_hash?(data)
|
||||
decoded_data = data.dup
|
||||
decoded_data = EncodeUtil.decode_utf16le(decoded_data)
|
||||
if DATA_REGEXP.match(decoded_data)
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
# Conver the value to a 64-Bit Little Endian Int
|
||||
# @param [String] val The string to convert
|
||||
def pack_int64le(val)
|
||||
[val & 0x00000000ffffffff, val >> 32].pack("V2")
|
||||
end
|
||||
|
||||
# Builds an array of strings that are 7 characters long
|
||||
# @param [String] str The string to split
|
||||
# @api private
|
||||
def split7(str)
|
||||
s = str.dup
|
||||
until s.empty?
|
||||
(ret ||= []).push s.slice!(0, 7)
|
||||
end
|
||||
ret
|
||||
end
|
||||
|
||||
# Not sure what this is doing
|
||||
# @param [String] str String to generate keys for
|
||||
# @api private
|
||||
def gen_keys(str)
|
||||
split7(str).map{ |str7|
|
||||
bits = split7(str7.unpack("B*")[0]).inject('')\
|
||||
{|ret, tkn| ret += tkn + (tkn.gsub('1', '').size % 2).to_s }
|
||||
[bits].pack("B*")
|
||||
}
|
||||
end
|
||||
|
||||
def apply_des(plain, keys)
|
||||
dec = OpenSSL::Cipher.new("des-cbc").encrypt
|
||||
dec.padding = 0
|
||||
keys.map {|k|
|
||||
dec.key = k
|
||||
dec.update(plain) + dec.final
|
||||
}
|
||||
end
|
||||
|
||||
# Generates a Lan Manager Hash
|
||||
# @param [String] password The password to base the hash on
|
||||
def lm_hash(password)
|
||||
keys = gen_keys password.upcase.ljust(14, "\0")
|
||||
apply_des(LM_MAGIC, keys).join
|
||||
end
|
||||
|
||||
# Generate a NTLM Hash
|
||||
# @param [String] password The password to base the hash on
|
||||
# @option opt :unicode (false) Unicode encode the password
|
||||
def ntlm_hash(password, opt = {})
|
||||
pwd = password.dup
|
||||
unless opt[:unicode]
|
||||
pwd = EncodeUtil.encode_utf16le(pwd)
|
||||
end
|
||||
OpenSSL::Digest::MD4.digest pwd
|
||||
end
|
||||
|
||||
# Generate a NTLMv2 Hash
|
||||
# @param [String] user The username
|
||||
# @param [String] password The password
|
||||
# @param [String] target The domain or workstation to authenticate to
|
||||
# @option opt :unicode (false) Unicode encode the domain
|
||||
def ntlmv2_hash(user, password, target, opt={})
|
||||
if is_ntlm_hash? password
|
||||
decoded_password = EncodeUtil.decode_utf16le(password)
|
||||
ntlmhash = [decoded_password.upcase[33,65]].pack('H32')
|
||||
else
|
||||
ntlmhash = ntlm_hash(password, opt)
|
||||
end
|
||||
userdomain = user.upcase + target
|
||||
unless opt[:unicode]
|
||||
userdomain = EncodeUtil.encode_utf16le(userdomain)
|
||||
end
|
||||
OpenSSL::HMAC.digest(OpenSSL::Digest::MD5.new, ntlmhash, userdomain)
|
||||
end
|
||||
|
||||
def lm_response(arg)
|
||||
begin
|
||||
hash = arg[:lm_hash]
|
||||
chal = arg[:challenge]
|
||||
rescue
|
||||
raise ArgumentError
|
||||
end
|
||||
chal = NTLM::pack_int64le(chal) if chal.is_a?(Integer)
|
||||
keys = gen_keys hash.ljust(21, "\0")
|
||||
apply_des(chal, keys).join
|
||||
end
|
||||
|
||||
def ntlm_response(arg)
|
||||
hash = arg[:ntlm_hash]
|
||||
chal = arg[:challenge]
|
||||
chal = NTLM::pack_int64le(chal) if chal.is_a?(Integer)
|
||||
keys = gen_keys hash.ljust(21, "\0")
|
||||
apply_des(chal, keys).join
|
||||
end
|
||||
|
||||
def ntlmv2_response(arg, opt = {})
|
||||
begin
|
||||
key = arg[:ntlmv2_hash]
|
||||
chal = arg[:challenge]
|
||||
ti = arg[:target_info]
|
||||
rescue
|
||||
raise ArgumentError
|
||||
end
|
||||
chal = NTLM::pack_int64le(chal) if chal.is_a?(Integer)
|
||||
|
||||
if opt[:client_challenge]
|
||||
cc = opt[:client_challenge]
|
||||
else
|
||||
cc = rand(MAX64)
|
||||
end
|
||||
cc = NTLM::pack_int64le(cc) if cc.is_a?(Integer)
|
||||
|
||||
if opt[:timestamp]
|
||||
ts = opt[:timestamp]
|
||||
else
|
||||
ts = Time.now.to_i
|
||||
end
|
||||
# epoch -> milsec from Jan 1, 1601
|
||||
ts = 10_000_000 * (ts + TIME_OFFSET)
|
||||
|
||||
blob = Blob.new
|
||||
blob.timestamp = ts
|
||||
blob.challenge = cc
|
||||
blob.target_info = ti
|
||||
|
||||
bb = blob.serialize
|
||||
|
||||
OpenSSL::HMAC.digest(OpenSSL::Digest::MD5.new, key, chal + bb) + bb
|
||||
end
|
||||
|
||||
def lmv2_response(arg, opt = {})
|
||||
key = arg[:ntlmv2_hash]
|
||||
chal = arg[:challenge]
|
||||
|
||||
chal = NTLM::pack_int64le(chal) if chal.is_a?(Integer)
|
||||
|
||||
if opt[:client_challenge]
|
||||
cc = opt[:client_challenge]
|
||||
else
|
||||
cc = rand(MAX64)
|
||||
end
|
||||
cc = NTLM::pack_int64le(cc) if cc.is_a?(Integer)
|
||||
|
||||
OpenSSL::HMAC.digest(OpenSSL::Digest::MD5.new, key, chal + cc) + cc
|
||||
end
|
||||
|
||||
def ntlm2_session(arg, opt = {})
|
||||
begin
|
||||
passwd_hash = arg[:ntlm_hash]
|
||||
chal = arg[:challenge]
|
||||
rescue
|
||||
raise ArgumentError
|
||||
end
|
||||
chal = NTLM::pack_int64le(chal) if chal.is_a?(Integer)
|
||||
|
||||
if opt[:client_challenge]
|
||||
cc = opt[:client_challenge]
|
||||
else
|
||||
cc = rand(MAX64)
|
||||
end
|
||||
cc = NTLM::pack_int64le(cc) if cc.is_a?(Integer)
|
||||
|
||||
keys = gen_keys(passwd_hash.ljust(21, "\0"))
|
||||
session_hash = OpenSSL::Digest::MD5.digest(chal + cc).slice(0, 8)
|
||||
response = apply_des(session_hash, keys).join
|
||||
[cc.ljust(24, "\0"), response]
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
28
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/net/ntlm/blob.rb
vendored
Normal file
28
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/net/ntlm/blob.rb
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
module Net
|
||||
module NTLM
|
||||
|
||||
BLOB_SIGN = 0x00000101
|
||||
|
||||
class Blob < FieldSet
|
||||
int32LE :blob_signature, {:value => BLOB_SIGN}
|
||||
int32LE :reserved, {:value => 0}
|
||||
int64LE :timestamp, {:value => 0}
|
||||
string :challenge, {:value => "", :size => 8}
|
||||
int32LE :unknown1, {:value => 0}
|
||||
string :target_info, {:value => "", :size => 0}
|
||||
int32LE :unknown2, {:value => 0}
|
||||
|
||||
def parse(str, offset=0)
|
||||
# 28 is the length of all fields before the variable-length
|
||||
# target_info field.
|
||||
if str.size > 28
|
||||
enable(:target_info)
|
||||
# Grab everything except the last 4 bytes (which will be :unknown2)
|
||||
self[:target_info].value = str[28..-5]
|
||||
end
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
65
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/net/ntlm/channel_binding.rb
vendored
Normal file
65
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/net/ntlm/channel_binding.rb
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
module Net
|
||||
module NTLM
|
||||
class ChannelBinding
|
||||
|
||||
# Creates a ChannelBinding used for Extended Protection Authentication
|
||||
# @see http://blogs.msdn.com/b/openspecification/archive/2013/03/26/ntlm-and-channel-binding-hash-aka-exteneded-protection-for-authentication.aspx
|
||||
#
|
||||
# @param outer_channel [OpenSSL::X509::Certificate] Server certificate securing
|
||||
# the outer TLS channel
|
||||
# @return [NTLM::ChannelBinding] A ChannelBinding holding a token that can be
|
||||
# embedded in a {Type3} message
|
||||
def self.create(outer_channel)
|
||||
new(outer_channel)
|
||||
end
|
||||
|
||||
# @param outer_channel [OpenSSL::X509::Certificate] Server certificate securing
|
||||
# the outer TLS channel
|
||||
def initialize(outer_channel)
|
||||
@channel = outer_channel
|
||||
@unique_prefix = 'tls-server-end-point'
|
||||
@initiator_addtype = 0
|
||||
@initiator_address_length = 0
|
||||
@acceptor_addrtype = 0
|
||||
@acceptor_address_length = 0
|
||||
end
|
||||
|
||||
attr_reader :channel, :unique_prefix, :initiator_addtype
|
||||
attr_reader :initiator_address_length, :acceptor_addrtype
|
||||
attr_reader :acceptor_address_length
|
||||
|
||||
# Returns a channel binding hash acceptable for use as a AV_PAIR MsvAvChannelBindings
|
||||
# field value as specified in the NTLM protocol
|
||||
#
|
||||
# @return [String] MD5 hash of gss_channel_bindings_struct
|
||||
def channel_binding_token
|
||||
@channel_binding_token ||= OpenSSL::Digest::MD5.new(gss_channel_bindings_struct).digest
|
||||
end
|
||||
|
||||
def gss_channel_bindings_struct
|
||||
@gss_channel_bindings_struct ||= begin
|
||||
token = [initiator_addtype].pack('I')
|
||||
token << [initiator_address_length].pack('I')
|
||||
token << [acceptor_addrtype].pack('I')
|
||||
token << [acceptor_address_length].pack('I')
|
||||
token << [application_data.length].pack('I')
|
||||
token << application_data
|
||||
token
|
||||
end
|
||||
end
|
||||
|
||||
def channel_hash
|
||||
@channel_hash ||= OpenSSL::Digest::SHA256.new(channel.to_der)
|
||||
end
|
||||
|
||||
def application_data
|
||||
@application_data ||= begin
|
||||
data = unique_prefix
|
||||
data << ':'
|
||||
data << channel_hash.digest
|
||||
data
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
65
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/net/ntlm/client.rb
vendored
Normal file
65
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/net/ntlm/client.rb
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
module Net
|
||||
module NTLM
|
||||
class Client
|
||||
|
||||
DEFAULT_FLAGS = NTLM::FLAGS[:UNICODE] | NTLM::FLAGS[:OEM] |
|
||||
NTLM::FLAGS[:SIGN] | NTLM::FLAGS[:SEAL] | NTLM::FLAGS[:REQUEST_TARGET] |
|
||||
NTLM::FLAGS[:NTLM] | NTLM::FLAGS[:ALWAYS_SIGN] | NTLM::FLAGS[:NTLM2_KEY] |
|
||||
NTLM::FLAGS[:KEY128] | NTLM::FLAGS[:KEY_EXCHANGE] | NTLM::FLAGS[:KEY56]
|
||||
|
||||
attr_reader :username, :password, :domain, :workstation, :flags
|
||||
|
||||
# @note All string parameters should be encoded in UTF-8. The proper
|
||||
# final encoding for placing in the various {Message messages} will be
|
||||
# chosen based on negotiation with the server.
|
||||
#
|
||||
# @param username [String]
|
||||
# @param password [String]
|
||||
# @option opts [String] :domain where we're authenticating to
|
||||
# @option opts [String] :workstation local workstation name
|
||||
# @option opts [Fixnum] :flags (DEFAULT_FLAGS) see Net::NTLM::Message::Type1.flag
|
||||
def initialize(username, password, opts = {})
|
||||
@username = username
|
||||
@password = password
|
||||
@domain = opts[:domain] || nil
|
||||
@workstation = opts[:workstation] || nil
|
||||
@flags = opts[:flags] || DEFAULT_FLAGS
|
||||
end
|
||||
|
||||
# @return [NTLM::Message]
|
||||
def init_context(resp = nil, channel_binding = nil)
|
||||
if resp.nil?
|
||||
@session = nil
|
||||
type1_message
|
||||
else
|
||||
@session = Client::Session.new(self, Net::NTLM::Message.decode64(resp), channel_binding)
|
||||
@session.authenticate!
|
||||
end
|
||||
end
|
||||
|
||||
# @return [Client::Session]
|
||||
def session
|
||||
@session
|
||||
end
|
||||
|
||||
def session_key
|
||||
@session.exported_session_key
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# @return [Message::Type1]
|
||||
def type1_message
|
||||
type1 = Message::Type1.new
|
||||
type1[:flag].value = flags
|
||||
type1.domain = domain if domain
|
||||
type1.workstation = workstation if workstation
|
||||
|
||||
type1
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
require "net/ntlm/client/session"
|
||||
237
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/net/ntlm/client/session.rb
vendored
Normal file
237
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/net/ntlm/client/session.rb
vendored
Normal file
@ -0,0 +1,237 @@
|
||||
module Net
|
||||
module NTLM
|
||||
class Client::Session
|
||||
|
||||
VERSION_MAGIC = "\x01\x00\x00\x00"
|
||||
TIME_OFFSET = 11644473600
|
||||
MAX64 = 0xffffffffffffffff
|
||||
CLIENT_TO_SERVER_SIGNING = "session key to client-to-server signing key magic constant\0"
|
||||
SERVER_TO_CLIENT_SIGNING = "session key to server-to-client signing key magic constant\0"
|
||||
CLIENT_TO_SERVER_SEALING = "session key to client-to-server sealing key magic constant\0"
|
||||
SERVER_TO_CLIENT_SEALING = "session key to server-to-client sealing key magic constant\0"
|
||||
|
||||
attr_reader :client, :challenge_message, :channel_binding
|
||||
|
||||
# @param client [Net::NTLM::Client] the client instance
|
||||
# @param challenge_message [Net::NTLM::Message::Type2] server message
|
||||
def initialize(client, challenge_message, channel_binding = nil)
|
||||
@client = client
|
||||
@challenge_message = challenge_message
|
||||
@channel_binding = channel_binding
|
||||
end
|
||||
|
||||
# Generate an NTLMv2 AUTHENTICATE_MESSAGE
|
||||
# @see http://msdn.microsoft.com/en-us/library/cc236643.aspx
|
||||
# @return [Net::NTLM::Message::Type3]
|
||||
def authenticate!
|
||||
calculate_user_session_key!
|
||||
type3_opts = {
|
||||
:lm_response => lmv2_resp,
|
||||
:ntlm_response => ntlmv2_resp,
|
||||
:domain => domain,
|
||||
:user => username,
|
||||
:workstation => workstation,
|
||||
:flag => (challenge_message.flag & client.flags)
|
||||
}
|
||||
t3 = Message::Type3.create type3_opts
|
||||
if negotiate_key_exchange?
|
||||
t3.enable(:session_key)
|
||||
rc4 = OpenSSL::Cipher.new("rc4")
|
||||
rc4.encrypt
|
||||
rc4.key = user_session_key
|
||||
sk = rc4.update exported_session_key
|
||||
sk << rc4.final
|
||||
t3.session_key = sk
|
||||
end
|
||||
t3
|
||||
end
|
||||
|
||||
def exported_session_key
|
||||
@exported_session_key ||=
|
||||
begin
|
||||
if negotiate_key_exchange?
|
||||
OpenSSL::Cipher.new("rc4").random_key
|
||||
else
|
||||
user_session_key
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def sign_message(message)
|
||||
seq = sequence
|
||||
sig = OpenSSL::HMAC.digest(OpenSSL::Digest::MD5.new, client_sign_key, "#{seq}#{message}")[0..7]
|
||||
if negotiate_key_exchange?
|
||||
sig = client_cipher.update sig
|
||||
sig << client_cipher.final
|
||||
end
|
||||
"#{VERSION_MAGIC}#{sig}#{seq}"
|
||||
end
|
||||
|
||||
def verify_signature(signature, message)
|
||||
seq = signature[-4..-1]
|
||||
sig = OpenSSL::HMAC.digest(OpenSSL::Digest::MD5.new, server_sign_key, "#{seq}#{message}")[0..7]
|
||||
if negotiate_key_exchange?
|
||||
sig = server_cipher.update sig
|
||||
sig << server_cipher.final
|
||||
end
|
||||
"#{VERSION_MAGIC}#{sig}#{seq}" == signature
|
||||
end
|
||||
|
||||
def seal_message(message)
|
||||
emessage = client_cipher.update(message)
|
||||
emessage + client_cipher.final
|
||||
end
|
||||
|
||||
def unseal_message(emessage)
|
||||
message = server_cipher.update(emessage)
|
||||
message + server_cipher.final
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
|
||||
def user_session_key
|
||||
@user_session_key ||= nil
|
||||
end
|
||||
|
||||
def sequence
|
||||
[raw_sequence].pack("V*")
|
||||
end
|
||||
|
||||
def raw_sequence
|
||||
if defined? @raw_sequence
|
||||
@raw_sequence += 1
|
||||
else
|
||||
@raw_sequence = 0
|
||||
end
|
||||
end
|
||||
|
||||
def client_sign_key
|
||||
@client_sign_key ||= OpenSSL::Digest::MD5.digest "#{exported_session_key}#{CLIENT_TO_SERVER_SIGNING}"
|
||||
end
|
||||
|
||||
def server_sign_key
|
||||
@server_sign_key ||= OpenSSL::Digest::MD5.digest "#{exported_session_key}#{SERVER_TO_CLIENT_SIGNING}"
|
||||
end
|
||||
|
||||
def client_seal_key
|
||||
@client_seal_key ||= OpenSSL::Digest::MD5.digest "#{exported_session_key}#{CLIENT_TO_SERVER_SEALING}"
|
||||
end
|
||||
|
||||
def server_seal_key
|
||||
@server_seal_key ||= OpenSSL::Digest::MD5.digest "#{exported_session_key}#{SERVER_TO_CLIENT_SEALING}"
|
||||
end
|
||||
|
||||
def client_cipher
|
||||
@client_cipher ||=
|
||||
begin
|
||||
rc4 = OpenSSL::Cipher.new("rc4")
|
||||
rc4.encrypt
|
||||
rc4.key = client_seal_key
|
||||
rc4
|
||||
end
|
||||
end
|
||||
|
||||
def server_cipher
|
||||
@server_cipher ||=
|
||||
begin
|
||||
rc4 = OpenSSL::Cipher.new("rc4")
|
||||
rc4.decrypt
|
||||
rc4.key = server_seal_key
|
||||
rc4
|
||||
end
|
||||
end
|
||||
|
||||
def client_challenge
|
||||
@client_challenge ||= NTLM.pack_int64le(rand(MAX64))
|
||||
end
|
||||
|
||||
def server_challenge
|
||||
@server_challenge ||= challenge_message[:challenge].serialize
|
||||
end
|
||||
|
||||
# epoch -> milsec from Jan 1, 1601
|
||||
# @see http://support.microsoft.com/kb/188768
|
||||
def timestamp
|
||||
@timestamp ||= 10_000_000 * (Time.now.to_i + TIME_OFFSET)
|
||||
end
|
||||
|
||||
def use_oem_strings?
|
||||
challenge_message.has_flag? :OEM
|
||||
end
|
||||
|
||||
def negotiate_key_exchange?
|
||||
challenge_message.has_flag? :KEY_EXCHANGE
|
||||
end
|
||||
|
||||
def username
|
||||
oem_or_unicode_str client.username
|
||||
end
|
||||
|
||||
def password
|
||||
oem_or_unicode_str client.password
|
||||
end
|
||||
|
||||
def workstation
|
||||
(client.workstation ? oem_or_unicode_str(client.workstation) : "")
|
||||
end
|
||||
|
||||
def domain
|
||||
(client.domain ? oem_or_unicode_str(client.domain) : "")
|
||||
end
|
||||
|
||||
def oem_or_unicode_str(str)
|
||||
if use_oem_strings?
|
||||
NTLM::EncodeUtil.decode_utf16le str
|
||||
else
|
||||
NTLM::EncodeUtil.encode_utf16le str
|
||||
end
|
||||
end
|
||||
|
||||
def ntlmv2_hash
|
||||
@ntlmv2_hash ||= NTLM.ntlmv2_hash(username, password, domain, {:client_challenge => client_challenge, :unicode => !use_oem_strings?})
|
||||
end
|
||||
|
||||
def calculate_user_session_key!
|
||||
@user_session_key = OpenSSL::HMAC.digest(OpenSSL::Digest::MD5.new, ntlmv2_hash, nt_proof_str)
|
||||
end
|
||||
|
||||
def lmv2_resp
|
||||
OpenSSL::HMAC.digest(OpenSSL::Digest::MD5.new, ntlmv2_hash, server_challenge + client_challenge) + client_challenge
|
||||
end
|
||||
|
||||
def ntlmv2_resp
|
||||
nt_proof_str + blob
|
||||
end
|
||||
|
||||
def nt_proof_str
|
||||
@nt_proof_str ||= OpenSSL::HMAC.digest(OpenSSL::Digest::MD5.new, ntlmv2_hash, server_challenge + blob)
|
||||
end
|
||||
|
||||
def blob
|
||||
@blob ||=
|
||||
begin
|
||||
b = Blob.new
|
||||
b.timestamp = timestamp
|
||||
b.challenge = client_challenge
|
||||
b.target_info = target_info
|
||||
b.serialize
|
||||
end
|
||||
end
|
||||
|
||||
def target_info
|
||||
@target_info ||= begin
|
||||
if channel_binding
|
||||
t = Net::NTLM::TargetInfo.new(challenge_message.target_info)
|
||||
av_id = Net::NTLM::TargetInfo::MSV_AV_CHANNEL_BINDINGS
|
||||
t.av_pairs[av_id] = channel_binding.channel_binding_token
|
||||
t.to_s
|
||||
else
|
||||
challenge_message.target_info
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
48
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/net/ntlm/encode_util.rb
vendored
Normal file
48
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/net/ntlm/encode_util.rb
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
module Net
|
||||
module NTLM
|
||||
|
||||
class EncodeUtil
|
||||
if RUBY_VERSION == "1.8.7"
|
||||
require "kconv"
|
||||
|
||||
# Decode a UTF16 string to a ASCII string
|
||||
# @param [String] str The string to convert
|
||||
def self.decode_utf16le(str)
|
||||
Kconv.kconv(swap16(str), Kconv::ASCII, Kconv::UTF16)
|
||||
end
|
||||
|
||||
# Encodes a ASCII string to a UTF16 string
|
||||
# @param [String] str The string to convert
|
||||
def self.encode_utf16le(str)
|
||||
swap16(Kconv.kconv(str, Kconv::UTF16, Kconv::ASCII))
|
||||
end
|
||||
|
||||
# Taggle the strings endianness between big/little and little/big
|
||||
# @param [String] str The string to swap the endianness on
|
||||
def self.swap16(str)
|
||||
str.unpack("v*").pack("n*")
|
||||
end
|
||||
else # Use native 1.9 string encoding functions
|
||||
|
||||
# Decode a UTF16 string to a ASCII string
|
||||
# @param [String] str The string to convert
|
||||
def self.decode_utf16le(str)
|
||||
str = str.dup.force_encoding(Encoding::UTF_16LE)
|
||||
str.encode(Encoding::UTF_8, Encoding::UTF_16LE).force_encoding('UTF-8')
|
||||
end
|
||||
|
||||
# Encodes a ASCII string to a UTF16 string
|
||||
# @param [String] str The string to convert
|
||||
# @note This implementation may seem stupid but the problem is that UTF16-LE and UTF-8 are incompatiable
|
||||
# encodings. This library uses string contatination to build the packet bytes. The end result is that
|
||||
# you can either marshal the encodings elsewhere of simply know that each time you call encode_utf16le
|
||||
# the function will convert the string bytes to UTF-16LE and note the encoding as UTF-8 so that byte
|
||||
# concatination works seamlessly.
|
||||
def self.encode_utf16le(str)
|
||||
str.dup.force_encoding('UTF-8').encode(Encoding::UTF_16LE, Encoding::UTF_8).force_encoding('UTF-8')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
14
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/net/ntlm/exceptions.rb
vendored
Normal file
14
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/net/ntlm/exceptions.rb
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
module Net
|
||||
module NTLM
|
||||
class NtlmError < StandardError; end
|
||||
|
||||
class InvalidTargetDataError < NtlmError
|
||||
attr_reader :data
|
||||
|
||||
def initialize(msg, data)
|
||||
@data = data
|
||||
super(msg)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
35
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/net/ntlm/field.rb
vendored
Normal file
35
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/net/ntlm/field.rb
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
module Net
|
||||
module NTLM
|
||||
|
||||
# base classes for primitives
|
||||
# @private
|
||||
class Field
|
||||
attr_accessor :active, :value
|
||||
|
||||
def initialize(opts)
|
||||
@value = opts[:value]
|
||||
@active = opts[:active].nil? ? true : opts[:active]
|
||||
@size = opts[:size].nil? ? 0 : opts[:size]
|
||||
end
|
||||
|
||||
def size
|
||||
@active ? @size : 0
|
||||
end
|
||||
|
||||
# Serializer function for field data
|
||||
# Exists in this class to be overridden by child classes
|
||||
def serialize
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
# Parser function for field data
|
||||
# Exists in this class to be overridden by child classes
|
||||
def parse(str, offset=0)
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
129
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/net/ntlm/field_set.rb
vendored
Normal file
129
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/net/ntlm/field_set.rb
vendored
Normal file
@ -0,0 +1,129 @@
|
||||
module Net
|
||||
module NTLM
|
||||
|
||||
# base class of data structure
|
||||
class FieldSet
|
||||
class << FieldSet
|
||||
|
||||
# @macro string_security_buffer
|
||||
# @method $1
|
||||
# @method $1=
|
||||
# @return [String]
|
||||
def string(name, opts)
|
||||
add_field(name, Net::NTLM::String, opts)
|
||||
end
|
||||
|
||||
# @macro int16le_security_buffer
|
||||
# @method $1
|
||||
# @method $1=
|
||||
# @return [Int16LE]
|
||||
def int16LE(name, opts)
|
||||
add_field(name, Net::NTLM::Int16LE, opts)
|
||||
end
|
||||
|
||||
# @macro int32le_security_buffer
|
||||
# @method $1
|
||||
# @method $1=
|
||||
# @return [Int32LE]
|
||||
def int32LE(name, opts)
|
||||
add_field(name, Net::NTLM::Int32LE, opts)
|
||||
end
|
||||
|
||||
# @macro int64le_security_buffer
|
||||
# @method $1
|
||||
# @method $1=
|
||||
# @return [Int64]
|
||||
def int64LE(name, opts)
|
||||
add_field(name, Net::NTLM::Int64LE, opts)
|
||||
end
|
||||
|
||||
# @macro security_buffer
|
||||
# @method $1
|
||||
# @method $1=
|
||||
# @return [SecurityBuffer]
|
||||
def security_buffer(name, opts)
|
||||
add_field(name, Net::NTLM::SecurityBuffer, opts)
|
||||
end
|
||||
|
||||
def prototypes
|
||||
@proto
|
||||
end
|
||||
|
||||
def names
|
||||
return [] if @proto.nil?
|
||||
@proto.map{|n, t, o| n}
|
||||
end
|
||||
|
||||
def types
|
||||
return [] if @proto.nil?
|
||||
@proto.map{|n, t, o| t}
|
||||
end
|
||||
|
||||
def opts
|
||||
return [] if @proto.nil?
|
||||
@proto.map{|n, t, o| o}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def add_field(name, type, opts)
|
||||
(@proto ||= []).push [name, type, opts]
|
||||
define_accessor name
|
||||
end
|
||||
|
||||
def define_accessor(name)
|
||||
module_eval(<<-End, __FILE__, __LINE__ + 1)
|
||||
def #{name}
|
||||
self['#{name}'].value
|
||||
end
|
||||
|
||||
def #{name}=(val)
|
||||
self['#{name}'].value = val
|
||||
end
|
||||
End
|
||||
end
|
||||
end
|
||||
|
||||
def initialize
|
||||
@alist = self.class.prototypes.map{ |n, t, o| [n, t.new(o)] }
|
||||
end
|
||||
|
||||
def parse(str, offset=0)
|
||||
@alist.inject(offset){|cur, a| cur += a[1].parse(str, cur)}
|
||||
end
|
||||
|
||||
def serialize
|
||||
@alist.map{|n, f| f.serialize }.join
|
||||
end
|
||||
|
||||
def size
|
||||
@alist.inject(0){|sum, a| sum += a[1].size}
|
||||
end
|
||||
|
||||
def [](name)
|
||||
a = @alist.assoc(name.to_s.intern)
|
||||
raise ArgumentError, "no such field: #{name}" unless a
|
||||
a[1]
|
||||
end
|
||||
|
||||
def []=(name, val)
|
||||
a = @alist.assoc(name.to_s.intern)
|
||||
raise ArgumentError, "no such field: #{name}" unless a
|
||||
a[1] = val
|
||||
end
|
||||
|
||||
def enable(name)
|
||||
self[name].active = true
|
||||
end
|
||||
|
||||
def disable(name)
|
||||
self[name].active = false
|
||||
end
|
||||
|
||||
def has_disabled_fields?
|
||||
@alist.any? { |name, field| !field.active }
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
26
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/net/ntlm/int16_le.rb
vendored
Normal file
26
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/net/ntlm/int16_le.rb
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
module Net
|
||||
module NTLM
|
||||
|
||||
class Int16LE < Field
|
||||
|
||||
def initialize(opt)
|
||||
super(opt)
|
||||
@size = 2
|
||||
end
|
||||
|
||||
def parse(str, offset=0)
|
||||
if @active and str.size >= offset + @size
|
||||
@value = str[offset, @size].unpack("v")[0]
|
||||
@size
|
||||
else
|
||||
0
|
||||
end
|
||||
end
|
||||
|
||||
def serialize
|
||||
[@value].pack("v")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
25
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/net/ntlm/int32_le.rb
vendored
Normal file
25
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/net/ntlm/int32_le.rb
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
module Net
|
||||
module NTLM
|
||||
|
||||
class Int32LE < Field
|
||||
def initialize(opt)
|
||||
super(opt)
|
||||
@size = 4
|
||||
end
|
||||
|
||||
def parse(str, offset=0)
|
||||
if @active and str.size >= offset + @size
|
||||
@value = str.slice(offset, @size).unpack("V")[0]
|
||||
@size
|
||||
else
|
||||
0
|
||||
end
|
||||
end
|
||||
|
||||
def serialize
|
||||
[@value].pack("V") if @active
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
26
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/net/ntlm/int64_le.rb
vendored
Normal file
26
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/net/ntlm/int64_le.rb
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
module Net
|
||||
module NTLM
|
||||
|
||||
class Int64LE < Field
|
||||
def initialize(opt)
|
||||
super(opt)
|
||||
@size = 8
|
||||
end
|
||||
|
||||
def parse(str, offset=0)
|
||||
if @active and str.size >= offset + @size
|
||||
d, u = str.slice(offset, @size).unpack("V2")
|
||||
@value = (u * 0x100000000 + d)
|
||||
@size
|
||||
else
|
||||
0
|
||||
end
|
||||
end
|
||||
|
||||
def serialize
|
||||
[@value & 0x00000000ffffffff, @value >> 32].pack("V2") if @active
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
129
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/net/ntlm/message.rb
vendored
Normal file
129
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/net/ntlm/message.rb
vendored
Normal file
@ -0,0 +1,129 @@
|
||||
module Net
|
||||
module NTLM
|
||||
|
||||
SSP_SIGN = "NTLMSSP\0"
|
||||
|
||||
FLAGS = {
|
||||
:UNICODE => 0x00000001,
|
||||
:OEM => 0x00000002,
|
||||
:REQUEST_TARGET => 0x00000004,
|
||||
:MBZ9 => 0x00000008,
|
||||
:SIGN => 0x00000010,
|
||||
:SEAL => 0x00000020,
|
||||
:NEG_DATAGRAM => 0x00000040,
|
||||
:NETWARE => 0x00000100,
|
||||
:NTLM => 0x00000200,
|
||||
:NEG_NT_ONLY => 0x00000400,
|
||||
:MBZ7 => 0x00000800,
|
||||
:DOMAIN_SUPPLIED => 0x00001000,
|
||||
:WORKSTATION_SUPPLIED => 0x00002000,
|
||||
:LOCAL_CALL => 0x00004000,
|
||||
:ALWAYS_SIGN => 0x00008000,
|
||||
:TARGET_TYPE_DOMAIN => 0x00010000,
|
||||
:NTLM2_KEY => 0x00080000,
|
||||
:TARGET_INFO => 0x00800000,
|
||||
:KEY128 => 0x20000000,
|
||||
:KEY_EXCHANGE => 0x40000000,
|
||||
:KEY56 => 0x80000000
|
||||
}.freeze
|
||||
|
||||
FLAG_KEYS = FLAGS.keys.sort{|a, b| FLAGS[a] <=> FLAGS[b] }
|
||||
|
||||
DEFAULT_FLAGS = {
|
||||
:TYPE1 => FLAGS[:UNICODE] | FLAGS[:OEM] | FLAGS[:REQUEST_TARGET] | FLAGS[:NTLM] | FLAGS[:ALWAYS_SIGN] | FLAGS[:NTLM2_KEY],
|
||||
:TYPE2 => FLAGS[:UNICODE],
|
||||
:TYPE3 => FLAGS[:UNICODE] | FLAGS[:REQUEST_TARGET] | FLAGS[:NTLM] | FLAGS[:ALWAYS_SIGN] | FLAGS[:NTLM2_KEY]
|
||||
}
|
||||
|
||||
|
||||
# @private false
|
||||
class Message < FieldSet
|
||||
class << Message
|
||||
def parse(str)
|
||||
m = Type0.new
|
||||
m.parse(str)
|
||||
case m.type
|
||||
when 1
|
||||
t = Type1.new.parse(str)
|
||||
when 2
|
||||
t = Type2.new.parse(str)
|
||||
when 3
|
||||
t = Type3.new.parse(str)
|
||||
else
|
||||
raise ArgumentError, "unknown type: #{m.type}"
|
||||
end
|
||||
t
|
||||
end
|
||||
|
||||
def decode64(str)
|
||||
parse(Base64.decode64(str))
|
||||
end
|
||||
end
|
||||
|
||||
# @return [self]
|
||||
def parse(str)
|
||||
super
|
||||
|
||||
while has_disabled_fields? && serialize.size < str.size
|
||||
# enable the next disabled field
|
||||
self.class.names.find { |name| !self[name].active && enable(name) }
|
||||
super
|
||||
end
|
||||
|
||||
self
|
||||
end
|
||||
|
||||
def has_flag?(flag)
|
||||
(self[:flag].value & FLAGS[flag]) == FLAGS[flag]
|
||||
end
|
||||
|
||||
def set_flag(flag)
|
||||
self[:flag].value |= FLAGS[flag]
|
||||
end
|
||||
|
||||
def dump_flags
|
||||
FLAG_KEYS.each{ |k| print(k, "=", has_flag?(k), "\n") }
|
||||
end
|
||||
|
||||
def serialize
|
||||
deflag
|
||||
super + security_buffers.map{|n, f| f.value}.join
|
||||
end
|
||||
|
||||
def encode64
|
||||
Base64.encode64(serialize).gsub(/\n/, '')
|
||||
end
|
||||
|
||||
def decode64(str)
|
||||
parse(Base64.decode64(str))
|
||||
end
|
||||
|
||||
alias head_size size
|
||||
|
||||
def data_size
|
||||
security_buffers.inject(0){|sum, a| sum += a[1].data_size}
|
||||
end
|
||||
|
||||
def size
|
||||
head_size + data_size
|
||||
end
|
||||
|
||||
|
||||
def security_buffers
|
||||
@alist.find_all{|n, f| f.instance_of?(SecurityBuffer)}
|
||||
end
|
||||
|
||||
def deflag
|
||||
security_buffers.inject(head_size){|cur, a|
|
||||
a[1].offset = cur
|
||||
cur += a[1].data_size
|
||||
}
|
||||
end
|
||||
|
||||
def data_edge
|
||||
security_buffers.map{ |n, f| f.active ? f.offset : size}.min
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
16
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/net/ntlm/message/type0.rb
vendored
Normal file
16
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/net/ntlm/message/type0.rb
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
module Net
|
||||
module NTLM
|
||||
class Message
|
||||
|
||||
# sub class definitions
|
||||
class Type0 < Message
|
||||
string :sign, {:size => 8, :value => SSP_SIGN}
|
||||
int32LE :type, {:value => 0}
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
18
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/net/ntlm/message/type1.rb
vendored
Normal file
18
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/net/ntlm/message/type1.rb
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
module Net
|
||||
module NTLM
|
||||
class Message
|
||||
|
||||
# @private false
|
||||
class Type1 < Message
|
||||
|
||||
string :sign, {:size => 8, :value => SSP_SIGN}
|
||||
int32LE :type, {:value => 1}
|
||||
int32LE :flag, {:value => DEFAULT_FLAGS[:TYPE1] }
|
||||
security_buffer :domain, {:value => ""}
|
||||
security_buffer :workstation, {:value => Socket.gethostname }
|
||||
string :os_version, {:size => 8, :value => "", :active => false }
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
102
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/net/ntlm/message/type2.rb
vendored
Normal file
102
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/net/ntlm/message/type2.rb
vendored
Normal file
@ -0,0 +1,102 @@
|
||||
module Net
|
||||
module NTLM
|
||||
class Message
|
||||
|
||||
# @private false
|
||||
class Type2 < Message
|
||||
|
||||
string :sign, { :size => 8, :value => SSP_SIGN }
|
||||
int32LE :type, { :value => 2 }
|
||||
security_buffer :target_name, { :size => 0, :value => "" }
|
||||
int32LE :flag, { :value => DEFAULT_FLAGS[:TYPE2] }
|
||||
int64LE :challenge, { :value => 0}
|
||||
int64LE :context, { :value => 0, :active => false }
|
||||
security_buffer :target_info, { :value => "", :active => false }
|
||||
string :os_version, { :size => 8, :value => "", :active => false }
|
||||
|
||||
# Generates a Type 3 response based on the Type 2 Information
|
||||
# @return [Type3]
|
||||
# @option arg [String] :username The username to authenticate with
|
||||
# @option arg [String] :password The user's password
|
||||
# @option arg [String] :domain ('') The domain to authenticate to
|
||||
# @option opt [String] :workstation (Socket.gethostname) The name of the calling workstation
|
||||
# @option opt [Boolean] :use_default_target (false) Use the domain supplied by the server in the Type 2 packet
|
||||
# @note An empty :domain option authenticates to the local machine.
|
||||
# @note The :use_default_target has precedence over the :domain option
|
||||
def response(arg, opt = {})
|
||||
usr = arg[:user]
|
||||
pwd = arg[:password]
|
||||
domain = arg[:domain] ? arg[:domain].upcase : ""
|
||||
if usr.nil? or pwd.nil?
|
||||
raise ArgumentError, "user and password have to be supplied"
|
||||
end
|
||||
|
||||
if opt[:workstation]
|
||||
ws = opt[:workstation]
|
||||
else
|
||||
ws = Socket.gethostname
|
||||
end
|
||||
|
||||
if opt[:client_challenge]
|
||||
cc = opt[:client_challenge]
|
||||
else
|
||||
cc = rand(MAX64)
|
||||
end
|
||||
cc = NTLM::pack_int64le(cc) if cc.is_a?(Integer)
|
||||
opt[:client_challenge] = cc
|
||||
|
||||
if has_flag?(:OEM) and opt[:unicode]
|
||||
usr = NTLM::EncodeUtil.decode_utf16le(usr)
|
||||
pwd = NTLM::EncodeUtil.decode_utf16le(pwd)
|
||||
ws = NTLM::EncodeUtil.decode_utf16le(ws)
|
||||
domain = NTLM::EncodeUtil.decode_utf16le(domain)
|
||||
opt[:unicode] = false
|
||||
end
|
||||
|
||||
if has_flag?(:UNICODE) and !opt[:unicode]
|
||||
usr = NTLM::EncodeUtil.encode_utf16le(usr)
|
||||
pwd = NTLM::EncodeUtil.encode_utf16le(pwd)
|
||||
ws = NTLM::EncodeUtil.encode_utf16le(ws)
|
||||
domain = NTLM::EncodeUtil.encode_utf16le(domain)
|
||||
opt[:unicode] = true
|
||||
end
|
||||
|
||||
if opt[:use_default_target]
|
||||
domain = self.target_name
|
||||
end
|
||||
|
||||
ti = self.target_info
|
||||
|
||||
chal = self[:challenge].serialize
|
||||
|
||||
if opt[:ntlmv2]
|
||||
ar = {:ntlmv2_hash => NTLM::ntlmv2_hash(usr, pwd, domain, opt), :challenge => chal, :target_info => ti}
|
||||
lm_res = NTLM::lmv2_response(ar, opt)
|
||||
ntlm_res = NTLM::ntlmv2_response(ar, opt)
|
||||
elsif has_flag?(:NTLM2_KEY)
|
||||
ar = {:ntlm_hash => NTLM::ntlm_hash(pwd, opt), :challenge => chal}
|
||||
lm_res, ntlm_res = NTLM::ntlm2_session(ar, opt)
|
||||
else
|
||||
ar = {:lm_hash => NTLM::lm_hash(pwd), :challenge => chal}
|
||||
lm_res = NTLM::lm_response(ar)
|
||||
ar = {:ntlm_hash => NTLM::ntlm_hash(pwd, opt), :challenge => chal}
|
||||
ntlm_res = NTLM::ntlm_response(ar)
|
||||
end
|
||||
|
||||
Type3.create({
|
||||
:lm_response => lm_res,
|
||||
:ntlm_response => ntlm_res,
|
||||
:domain => domain,
|
||||
:user => usr,
|
||||
:workstation => ws,
|
||||
:flag => self.flag
|
||||
})
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
131
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/net/ntlm/message/type3.rb
vendored
Normal file
131
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/net/ntlm/message/type3.rb
vendored
Normal file
@ -0,0 +1,131 @@
|
||||
module Net
|
||||
module NTLM
|
||||
class Message
|
||||
|
||||
# @private false
|
||||
class Type3 < Message
|
||||
|
||||
string :sign, {:size => 8, :value => SSP_SIGN}
|
||||
int32LE :type, {:value => 3}
|
||||
security_buffer :lm_response, {:value => ""}
|
||||
security_buffer :ntlm_response, {:value => ""}
|
||||
security_buffer :domain, {:value => ""}
|
||||
security_buffer :user, {:value => ""}
|
||||
security_buffer :workstation, {:value => ""}
|
||||
security_buffer :session_key, {:value => "", :active => false }
|
||||
int32LE :flag, {:value => 0, :active => false }
|
||||
string :os_version, {:size => 8, :active => false }
|
||||
|
||||
class << Type3
|
||||
# Builds a Type 3 packet
|
||||
# @note All options must be properly encoded with either unicode or oem encoding
|
||||
# @return [Type3]
|
||||
# @option arg [String] :lm_response The LM hash
|
||||
# @option arg [String] :ntlm_response The NTLM hash
|
||||
# @option arg [String] :domain The domain to authenticate to
|
||||
# @option arg [String] :workstation The name of the calling workstation
|
||||
# @option arg [String] :session_key The session key
|
||||
# @option arg [Integer] :flag Flags for the packet
|
||||
def create(arg, opt ={})
|
||||
t = new
|
||||
t.lm_response = arg[:lm_response]
|
||||
t.ntlm_response = arg[:ntlm_response]
|
||||
t.domain = arg[:domain]
|
||||
t.user = arg[:user]
|
||||
|
||||
if arg[:workstation]
|
||||
t.workstation = arg[:workstation]
|
||||
end
|
||||
|
||||
if arg[:session_key]
|
||||
t.enable(:session_key)
|
||||
t.session_key = arg[:session_key]
|
||||
end
|
||||
|
||||
if arg[:flag]
|
||||
t.enable(:session_key)
|
||||
t.enable(:flag)
|
||||
t.flag = arg[:flag]
|
||||
end
|
||||
t
|
||||
end
|
||||
end
|
||||
|
||||
# @param server_challenge (see #password?)
|
||||
def blank_password?(server_challenge)
|
||||
password?('', server_challenge)
|
||||
end
|
||||
|
||||
# @param password [String]
|
||||
# @param server_challenge [String] The server's {Type2#challenge challenge} from the
|
||||
# {Type2} message for which this object is a response.
|
||||
# @return [true] if +password+ was the password used to generate this
|
||||
# {Type3} message
|
||||
# @return [false] otherwise
|
||||
def password?(password, server_challenge)
|
||||
case ntlm_version
|
||||
when :ntlm2_session
|
||||
ntlm2_session_password?(password, server_challenge)
|
||||
when :ntlmv2
|
||||
ntlmv2_password?(password, server_challenge)
|
||||
else
|
||||
raise
|
||||
end
|
||||
end
|
||||
|
||||
# @return [Symbol]
|
||||
def ntlm_version
|
||||
if ntlm_response.size == 24 && lm_response[0,8] != "\x00"*8 && lm_response[8,16] == "\x00"*16
|
||||
:ntlm2_session
|
||||
elsif ntlm_response.size == 24
|
||||
:ntlmv1
|
||||
elsif ntlm_response.size > 24
|
||||
:ntlmv2
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def ntlm2_session_password?(password, server_challenge)
|
||||
hash = ntlm_response
|
||||
_lm, empty_hash = NTLM.ntlm2_session(
|
||||
{
|
||||
:ntlm_hash => NTLM.ntlm_hash(password),
|
||||
:challenge => server_challenge,
|
||||
},
|
||||
{
|
||||
:client_challenge => lm_response[0,8]
|
||||
}
|
||||
)
|
||||
hash == empty_hash
|
||||
end
|
||||
|
||||
def ntlmv2_password?(password, server_challenge)
|
||||
|
||||
# The first 16 bytes of the ntlm_response are the HMAC of the blob
|
||||
# that follows it.
|
||||
blob = Blob.new
|
||||
blob.parse(ntlm_response[16..-1])
|
||||
|
||||
empty_hash = NTLM.ntlmv2_response(
|
||||
{
|
||||
# user and domain came from the serialized data here, so
|
||||
# they're already unicode
|
||||
:ntlmv2_hash => NTLM.ntlmv2_hash(user, '', domain, :unicode => true),
|
||||
:challenge => server_challenge,
|
||||
:target_info => blob.target_info
|
||||
},
|
||||
{
|
||||
:client_challenge => blob.challenge,
|
||||
# The blob's timestamp is already in milliseconds since 1601,
|
||||
# so convert it back to epoch time first
|
||||
:timestamp => (blob.timestamp / 10_000_000) - NTLM::TIME_OFFSET,
|
||||
}
|
||||
)
|
||||
|
||||
empty_hash == ntlm_response
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
48
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/net/ntlm/security_buffer.rb
vendored
Normal file
48
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/net/ntlm/security_buffer.rb
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
|
||||
module Net
|
||||
module NTLM
|
||||
|
||||
class SecurityBuffer < FieldSet
|
||||
|
||||
int16LE :length, {:value => 0}
|
||||
int16LE :allocated, {:value => 0}
|
||||
int32LE :offset, {:value => 0}
|
||||
|
||||
attr_accessor :active
|
||||
def initialize(opts={})
|
||||
super()
|
||||
@value = opts[:value]
|
||||
@active = opts[:active].nil? ? true : opts[:active]
|
||||
@size = 8
|
||||
end
|
||||
|
||||
def parse(str, offset=0)
|
||||
if @active and str.size >= offset + @size
|
||||
super(str, offset)
|
||||
@value = str[self.offset, self.length]
|
||||
@size
|
||||
else
|
||||
0
|
||||
end
|
||||
end
|
||||
|
||||
def serialize
|
||||
super if @active
|
||||
end
|
||||
|
||||
def value
|
||||
@value
|
||||
end
|
||||
|
||||
def value=(val)
|
||||
@value = val
|
||||
self.length = self.allocated = val.size
|
||||
end
|
||||
|
||||
def data_size
|
||||
@active ? @value.size : 0
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
35
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/net/ntlm/string.rb
vendored
Normal file
35
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/net/ntlm/string.rb
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
module Net
|
||||
module NTLM
|
||||
|
||||
class String < Field
|
||||
def initialize(opts)
|
||||
super(opts)
|
||||
@size = opts[:size]
|
||||
end
|
||||
|
||||
def parse(str, offset=0)
|
||||
if @active and str.size >= offset + @size
|
||||
@value = str[offset, @size]
|
||||
@size
|
||||
else
|
||||
0
|
||||
end
|
||||
end
|
||||
|
||||
def serialize
|
||||
if @active
|
||||
@value.to_s
|
||||
else
|
||||
""
|
||||
end
|
||||
end
|
||||
|
||||
def value=(val)
|
||||
@value = val
|
||||
@size = @value.nil? ? 0 : @value.size
|
||||
@active = (@size > 0)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
89
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/net/ntlm/target_info.rb
vendored
Normal file
89
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/net/ntlm/target_info.rb
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
module Net
|
||||
module NTLM
|
||||
|
||||
# Represents a list of AV_PAIR structures
|
||||
# @see https://msdn.microsoft.com/en-us/library/cc236646.aspx
|
||||
class TargetInfo
|
||||
|
||||
# Allowed AvId values for an AV_PAIR
|
||||
MSV_AV_EOL = "\x00\x00".freeze
|
||||
MSV_AV_NB_COMPUTER_NAME = "\x01\x00".freeze
|
||||
MSV_AV_NB_DOMAIN_NAME = "\x02\x00".freeze
|
||||
MSV_AV_DNS_COMPUTER_NAME = "\x03\x00".freeze
|
||||
MSV_AV_DNS_DOMAIN_NAME = "\x04\x00".freeze
|
||||
MSV_AV_DNS_TREE_NAME = "\x05\x00".freeze
|
||||
MSV_AV_FLAGS = "\x06\x00".freeze
|
||||
MSV_AV_TIMESTAMP = "\x07\x00".freeze
|
||||
MSV_AV_SINGLE_HOST = "\x08\x00".freeze
|
||||
MSV_AV_TARGET_NAME = "\x09\x00".freeze
|
||||
MSV_AV_CHANNEL_BINDINGS = "\x0A\x00".freeze
|
||||
|
||||
# @param av_pair_sequence [String] AV_PAIR list from challenge message
|
||||
def initialize(av_pair_sequence)
|
||||
@av_pairs = read_pairs(av_pair_sequence)
|
||||
end
|
||||
|
||||
attr_reader :av_pairs
|
||||
|
||||
def to_s
|
||||
result = ''
|
||||
av_pairs.each do |k,v|
|
||||
result << k
|
||||
result << [v.length].pack('S')
|
||||
result << v
|
||||
end
|
||||
result << Net::NTLM::TargetInfo::MSV_AV_EOL
|
||||
result << [0].pack('S')
|
||||
result.force_encoding(Encoding::ASCII_8BIT)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
VALID_PAIR_ID = [
|
||||
MSV_AV_EOL,
|
||||
MSV_AV_NB_COMPUTER_NAME,
|
||||
MSV_AV_NB_DOMAIN_NAME,
|
||||
MSV_AV_DNS_COMPUTER_NAME,
|
||||
MSV_AV_DNS_DOMAIN_NAME,
|
||||
MSV_AV_DNS_TREE_NAME,
|
||||
MSV_AV_FLAGS,
|
||||
MSV_AV_TIMESTAMP,
|
||||
MSV_AV_SINGLE_HOST,
|
||||
MSV_AV_TARGET_NAME,
|
||||
MSV_AV_CHANNEL_BINDINGS
|
||||
].freeze
|
||||
|
||||
def read_pairs(av_pair_sequence)
|
||||
offset = 0
|
||||
result = {}
|
||||
return result if av_pair_sequence.nil?
|
||||
|
||||
until offset >= av_pair_sequence.length
|
||||
id = av_pair_sequence[offset..offset+1]
|
||||
|
||||
unless VALID_PAIR_ID.include?(id)
|
||||
raise Net::NTLM::InvalidTargetDataError.new(
|
||||
"Invalid AvId #{to_hex(id)} in AV_PAIR structure",
|
||||
av_pair_sequence
|
||||
)
|
||||
end
|
||||
|
||||
length = av_pair_sequence[offset+2..offset+3].unpack('S')[0].to_i
|
||||
if length > 0
|
||||
value = av_pair_sequence[offset+4..offset+4+length-1]
|
||||
result[id] = value
|
||||
end
|
||||
|
||||
offset += 4 + length
|
||||
end
|
||||
|
||||
result
|
||||
end
|
||||
|
||||
def to_hex(str)
|
||||
return nil if str.nil?
|
||||
str.bytes.map {|b| '0x' + b.to_s(16).rjust(2,'0').upcase}.join('-')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
11
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/net/ntlm/version.rb
vendored
Normal file
11
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/net/ntlm/version.rb
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
module Net
|
||||
module NTLM
|
||||
# @private
|
||||
module VERSION
|
||||
MAJOR = 0
|
||||
MINOR = 6
|
||||
TINY = 3
|
||||
STRING = [MAJOR, MINOR, TINY].join('.')
|
||||
end
|
||||
end
|
||||
end
|
||||
1
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/rubyntlm.rb
vendored
Normal file
1
Library/Homebrew/vendor/bundle/ruby/2.6.0/gems/rubyntlm-0.6.3/lib/rubyntlm.rb
vendored
Normal file
@ -0,0 +1 @@
|
||||
require 'net/ntlm'
|
||||
Loading…
x
Reference in New Issue
Block a user