ruby_smb 3.2.6 → 3.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/lib/ruby_smb/server/server_client/share_io.rb +2 -2
- data/lib/ruby_smb/server/share/provider/disk.rb +2 -2
- data/lib/ruby_smb/server/share/provider/processor.rb +25 -0
- data/lib/ruby_smb/server/share/provider/virtual_disk.rb +3 -3
- data/lib/ruby_smb/server/share/provider.rb +48 -1
- data/lib/ruby_smb/smb1/packet/nt_create_andx_request.rb +1 -1
- data/lib/ruby_smb/smb2/create_context.rb +5 -2
- data/lib/ruby_smb/version.rb +1 -1
- data/spec/lib/ruby_smb/smb2/create_context/create_context_request_spec.rb +35 -0
- data.tar.gz.sig +0 -0
- metadata +25 -84
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e4ddd94d3c783b3091a37c946c5069da85350c23294b33ddabcdc0476f828ec4
|
4
|
+
data.tar.gz: 990ad64d98bd60dd957c1b8b6fcf1abdbd6e8a52d408e0e6c03d3694354cb4ad
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bc7b1921009d55e8263ecfe3aa282bd4df35636a5055f5126ffa1866ed8140283bbfa14f341a4d791e30a7f51e0df631676ef211961c9712e457e0939983a6c7
|
7
|
+
data.tar.gz: 11982c6c2b2fb653756140c7024ccff301c72ee9b5ac44f85a5071f1d2a27dbdcf31b5936bc3ea646ef7219e3c917b5466ec3e6b26bbba116fc7552169244a4a
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
@@ -11,7 +11,7 @@ module RubySMB
|
|
11
11
|
end
|
12
12
|
|
13
13
|
logger.debug("Received #{SMB1::Commands.name(request.smb_header.command)} request for share: #{share_processor.provider.name}")
|
14
|
-
share_processor.
|
14
|
+
share_processor.share_io(__callee__, request)
|
15
15
|
end
|
16
16
|
|
17
17
|
alias :do_close_smb1 :proxy_share_io_smb1
|
@@ -29,7 +29,7 @@ module RubySMB
|
|
29
29
|
end
|
30
30
|
|
31
31
|
logger.debug("Received #{SMB2::Commands.name(request.smb2_header.command)} request for share: #{share_processor.provider.name}")
|
32
|
-
share_processor.
|
32
|
+
share_processor.share_io(__callee__, request)
|
33
33
|
end
|
34
34
|
|
35
35
|
alias :do_close_smb2 :proxy_share_io_smb2
|
@@ -14,13 +14,13 @@ module RubySMB
|
|
14
14
|
# @param [String] name The name of this share.
|
15
15
|
# @param [String, Pathname] path The local file system path to share. This path must be an absolute path to an existing
|
16
16
|
# directory.
|
17
|
-
def initialize(name, path)
|
17
|
+
def initialize(name, path, hooks: nil)
|
18
18
|
path = Pathname.new(File.expand_path(path)) if path.is_a?(String)
|
19
19
|
raise ArgumentError.new('path must be a directory') unless path.directory? # it needs to exist
|
20
20
|
raise ArgumentError.new('path must be absolute') unless path.absolute? # it needs to be absolute so it is independent of the cwd
|
21
21
|
|
22
22
|
@path = path
|
23
|
-
super(name)
|
23
|
+
super(name, hooks: hooks)
|
24
24
|
end
|
25
25
|
|
26
26
|
attr_accessor :path
|
@@ -80,6 +80,31 @@ module RubySMB
|
|
80
80
|
@server_client.server
|
81
81
|
end
|
82
82
|
|
83
|
+
# Forward a share IO method for a particular request. This is a choke point to allow any hooks that were
|
84
|
+
# registered with the share provider to be executed before and after the specified method is invoked to
|
85
|
+
# process the request and generate the response. This is used for both SMB1 and SMB2 requests.
|
86
|
+
#
|
87
|
+
# @param [Symbol] method_name The method name to forward the request to
|
88
|
+
# @param [RubySMB::GenericPacket] request The request packet to be processed
|
89
|
+
# @return [RubySMB::GenericPacket]
|
90
|
+
def share_io(method_name, request)
|
91
|
+
@provider.hooks.each do |hook|
|
92
|
+
next unless hook.request_class == request.class && hook.location == :before
|
93
|
+
|
94
|
+
request = hook.callback.call(@session, request) || request
|
95
|
+
end
|
96
|
+
|
97
|
+
response = send(method_name, request)
|
98
|
+
|
99
|
+
@provider.hooks.each do |hook|
|
100
|
+
next unless hook.request_class == request.class && hook.location == :after
|
101
|
+
|
102
|
+
response = hook.callback.call(@session, request, response) || response
|
103
|
+
end
|
104
|
+
|
105
|
+
response
|
106
|
+
end
|
107
|
+
|
83
108
|
# The underlying share provider that this is a processor for.
|
84
109
|
# @!attribute [r] provider
|
85
110
|
# @return [RubySMB::Server::Share::Provider::Base]
|
@@ -14,9 +14,9 @@ module RubySMB
|
|
14
14
|
private_constant :HASH_METHODS
|
15
15
|
|
16
16
|
# @param [String] name The name of this share.
|
17
|
-
def initialize(name)
|
17
|
+
def initialize(name, hooks: nil)
|
18
18
|
@vfs = {}
|
19
|
-
super(name, add(VirtualPathname.new(self, File::SEPARATOR)))
|
19
|
+
super(name, add(VirtualPathname.new(self, File::SEPARATOR)), hooks: hooks)
|
20
20
|
end
|
21
21
|
|
22
22
|
# Add a dynamic file to the virtual file system. A dynamic file is one whose contents are generated by the
|
@@ -86,7 +86,7 @@ module RubySMB
|
|
86
86
|
end
|
87
87
|
|
88
88
|
def new_processor(server_client, session)
|
89
|
-
scoped_virtual_disk = self.class.new(@name)
|
89
|
+
scoped_virtual_disk = self.class.new(@name, hooks: @hooks)
|
90
90
|
@vfs.each_value do |path|
|
91
91
|
path = path.dup
|
92
92
|
path.virtual_disk = scoped_virtual_disk if path.is_a?(VirtualPathname)
|
@@ -6,9 +6,51 @@ module RubySMB
|
|
6
6
|
# type and name. It is shared across all client connections and
|
7
7
|
# sessions.
|
8
8
|
class Base
|
9
|
+
Hook = Struct.new(:request_class, :location, :callback)
|
10
|
+
|
9
11
|
# @param [String] name The name of this share.
|
10
|
-
def initialize(name)
|
12
|
+
def initialize(name, hooks: nil)
|
11
13
|
@name = name
|
14
|
+
@hooks = hooks || []
|
15
|
+
end
|
16
|
+
|
17
|
+
# Add a hook to be called when the specified request class is processed. Any hook that was previously
|
18
|
+
# installed for the request class and location will be removed. A hook installed with a location of :before
|
19
|
+
# will be called with the session and request as the only two arguments. The return value, if provided, will
|
20
|
+
# replace the request that is to be processed. A hook installed with a location of :after will be called with
|
21
|
+
# the session, request and response as the only three arguments. The return value, if provided, will replace
|
22
|
+
# the response that is to be sent to the client.
|
23
|
+
#
|
24
|
+
# @param [RubySMB::GenericPacket] request_class The request class to register the hook for.
|
25
|
+
# @param [Proc] callback The routine to be executed when the request class is being processed.
|
26
|
+
# @param [Symbol] location When the callback should be invoked. Must be either :before or :after.
|
27
|
+
def add_hook(request_class, callback: nil, location: :before, &block)
|
28
|
+
unless %i[ before after ].include?(location)
|
29
|
+
raise ArgumentError, 'the location argument must be :before or :after'
|
30
|
+
end
|
31
|
+
|
32
|
+
unless callback.nil? ^ block.nil?
|
33
|
+
raise ArgumentError, 'either a callback or a block must be specified'
|
34
|
+
end
|
35
|
+
|
36
|
+
# Remove any hooks that were previously installed, this enforces that only one hook can be present at a time
|
37
|
+
# for any particular request class and location combination.
|
38
|
+
remove_hook(request_class, location: location)
|
39
|
+
@hooks << Hook.new(request_class, location, callback || block)
|
40
|
+
|
41
|
+
nil
|
42
|
+
end
|
43
|
+
|
44
|
+
# Remove a hook for the specified request class.
|
45
|
+
#
|
46
|
+
# @param [RubySMB::GenericPacket] request_class The request class to register the hook for.
|
47
|
+
# @param [Symbol] location When the callback should be invoked.
|
48
|
+
def remove_hook(request_class, location: :before)
|
49
|
+
@hooks.filter! do |hook|
|
50
|
+
hook.request_class == request_class && hook.location == location
|
51
|
+
end
|
52
|
+
|
53
|
+
nil
|
12
54
|
end
|
13
55
|
|
14
56
|
# Create a new, session-specific processor instance for this share.
|
@@ -28,6 +70,11 @@ module RubySMB
|
|
28
70
|
# @!attribute [r] name
|
29
71
|
# @return [String]
|
30
72
|
attr_accessor :name
|
73
|
+
|
74
|
+
# The hooks installed for this share.
|
75
|
+
# @!attribute [r] hooks
|
76
|
+
# @return [Array]
|
77
|
+
attr_accessor :hooks
|
31
78
|
end
|
32
79
|
end
|
33
80
|
end
|
@@ -35,7 +35,7 @@ module RubySMB
|
|
35
35
|
end
|
36
36
|
|
37
37
|
uint64 :allocation_size, label: 'Allocation Size'
|
38
|
-
smb_ext_file_attributes :ext_file_attributes, label: '
|
38
|
+
smb_ext_file_attributes :ext_file_attributes, label: 'Extended File Attributes'
|
39
39
|
share_access :share_access, label: 'Share Access'
|
40
40
|
# The following constants are defined in RubySMB::Dispositions
|
41
41
|
uint32 :create_disposition, label: 'Create Disposition'
|
@@ -51,8 +51,11 @@ module RubySMB
|
|
51
51
|
def calc_buffer_size
|
52
52
|
align = 8
|
53
53
|
size = 0
|
54
|
-
size += name_length
|
55
|
-
size +=
|
54
|
+
size += name_length
|
55
|
+
size += ((align - size % align) % align) if name_offset < data_offset
|
56
|
+
size += data_length
|
57
|
+
size += ((align - size % align) % align) if data_offset < name_offset
|
58
|
+
size += ((align - size % align) % align) if next_offset != 0
|
56
59
|
size
|
57
60
|
end
|
58
61
|
|
data/lib/ruby_smb/version.rb
CHANGED
@@ -8,6 +8,7 @@ RSpec.describe RubySMB::SMB2::CreateContext::CreateContextRequest do
|
|
8
8
|
it { is_expected.to respond_to :name_length }
|
9
9
|
it { is_expected.to respond_to :data_offset }
|
10
10
|
it { is_expected.to respond_to :data_length }
|
11
|
+
it { is_expected.to respond_to :buffer }
|
11
12
|
it { is_expected.to respond_to :name }
|
12
13
|
it { is_expected.to respond_to :data }
|
13
14
|
|
@@ -39,4 +40,38 @@ RSpec.describe RubySMB::SMB2::CreateContext::CreateContextRequest do
|
|
39
40
|
expect(struct.data_offset).to eq 0
|
40
41
|
end
|
41
42
|
end
|
43
|
+
|
44
|
+
context 'when reading a packet with extra padding' do
|
45
|
+
# :name_offset=>120,
|
46
|
+
# :name_length=>14,
|
47
|
+
# :contexts_offset=>136,
|
48
|
+
# :contexts_length=>60,
|
49
|
+
# :bytes_remaining=>76,
|
50
|
+
# :buffer=> "t\x00e\x00s\x00t\x00.\x00r\x00b\x00\x00\x00\x00\x00\x00[...SNIP...]"
|
51
|
+
let(:raw_data) {
|
52
|
+
"\x00\x00\x00\x00\x10\x00\x04\x00\x00\x00\x18\x00\x24\x00\x00\x00\x44\x48\x32\x43\x00\x00"\
|
53
|
+
"\x00\x00\x04\xfa\xb6\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd7\x43\xe0\x35"\
|
54
|
+
"\x5c\x6e\xee\x11\xb8\xbb\x00\x0c\x29\xc1\x13\xd0\x00\x00\x00\x00".b
|
55
|
+
}
|
56
|
+
|
57
|
+
it 'reads without error' do
|
58
|
+
expect { described_class.read(raw_data) }.to_not raise_error
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'when getting #name and #data' do
|
62
|
+
let(:create_request_packet) { described_class.read(raw_data) }
|
63
|
+
|
64
|
+
it 'gets the expected #name value' do
|
65
|
+
create_request_packet.name.read_now!
|
66
|
+
expect(create_request_packet.name).to eq 'DH2C'
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'gets the expected #data value' do
|
70
|
+
create_request_packet.data.read_now!
|
71
|
+
expected_data = "\x04\xfa\xb6\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd7\x43"\
|
72
|
+
"\xe0\x35\x5c\x6e\xee\x11\xb8\xbb\x00\x0c\x29\xc1\x13\xd0\x00\x00\x00\x00".b
|
73
|
+
expect(create_request_packet.data).to eq expected_data
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
42
77
|
end
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby_smb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.2.
|
4
|
+
version: 3.2.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Metasploit Hackers
|
@@ -14,90 +14,31 @@ bindir: bin
|
|
14
14
|
cert_chain:
|
15
15
|
- |
|
16
16
|
-----BEGIN CERTIFICATE-----
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
+
|
17
|
+
MIIERDCCAqygAwIBAgIBATANBgkqhkiG9w0BAQsFADAmMSQwIgYDVQQDDBttc2Zk
|
18
|
+
ZXYvREM9bWV0YXNwbG9pdC9EQz1jb20wHhcNMjMxMDMwMTYwNDI1WhcNMjUxMDI5
|
19
|
+
MTYwNDI1WjAmMSQwIgYDVQQDDBttc2ZkZXYvREM9bWV0YXNwbG9pdC9EQz1jb20w
|
20
|
+
ggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQDZN/EKv+yVjwiKWvjAVhjF
|
21
|
+
aWNYI0E9bJ5d1qKd29omRYX9a+OOKBCu5+394fyF5RjwU4mYGr2iopX9ixRJrWXH
|
22
|
+
ojs70tEvV1CmvP9rhz7JKzQQoJOkinrz4d+StIylxVxVdgm7DeiB3ruTwvl7qKUv
|
23
|
+
piWzhrBFiVU6XIEAwq6wNEmnv2D+Omyf4h0Tf99hc6G0QmBnU3XydqvnZ+AzUbBV
|
24
|
+
24RH3+NQoigLbvK4M5aOeYhk19di58hznebOw6twHzNczshrBeMFQp985ScNgsvF
|
25
|
+
rL+7HNNwpcpngERwZfzDNn7iYN5X3cyvTcykShtsuPMa5zXsYo42LZrsTF87DW38
|
26
|
+
D8sxL6Dgdqu25Mltdw9m+iD4rHSfb1KJYEoNO+WwBJLO2Y4d6G1CR66tVeWsZspb
|
27
|
+
zneOVC+sDuil7hOm+6a7Y2yrrRyT6IfL/07DywjPAIRUp5+Jn8ZrkWRNo2AOwWBG
|
28
|
+
k5gz7SfJPHuyVnPlxoMA0MTFCUnnnbyHu882TGoJGgMCAwEAAaN9MHswCQYDVR0T
|
29
|
+
BAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFIQfNa4E889ZE334cwU7eNu2hScH
|
30
|
+
MCAGA1UdEQQZMBeBFW1zZmRldkBtZXRhc3Bsb2l0LmNvbTAgBgNVHRIEGTAXgRVt
|
31
|
+
c2ZkZXZAbWV0YXNwbG9pdC5jb20wDQYJKoZIhvcNAQELBQADggGBAMfzvKcV27p7
|
32
|
+
pctmpW2JmIXLMrjNLyGJAxELH/t9pJueXdga7uj2fJkYQDbwGw5x4MGyFqhqJLH4
|
33
|
+
l/qsUF3PyAXDTSWLVaqXQVWO+IIHxecG0XjPXTNudzMU0hzqbqiBKvsW7/a3V5BP
|
34
|
+
SWlFzrFkoXWlPouFpoakyYMJjpW4SGdPzRv7pM4OhXtkXpHiRvx5985FrHgHlI89
|
35
|
+
NSIuIUbp8zqk4hP1i9MV0Lc/vTf2gOmo+RHnjqG1NiYfMCYyY/Mcd4W36kGOl468
|
36
|
+
I8VDTwgCufkAzFu7BJ5yCOueqtDcuq+d3YhAyU7NI4+Ja8EwazOnB+07sWhKpg7z
|
37
|
+
yuQ1mWYPmZfVQpoSVv1CvXsoqJYXVPBBLOacKKSj8ArVG6pPn9Bej7IOQdblaFjl
|
38
|
+
DgscAao7wB3xW2BWEp1KnaDWkf1x9ttgoBEYyuYwU7uatB67kBQG1PKvLt79wHvz
|
39
|
+
Dxs+KOjGbBRfMnPgVGYkORKVrZIwlaboHbDKxcVW5xv+oZc7KYXWGg==
|
37
40
|
-----END CERTIFICATE-----
|
38
|
-
-
|
39
|
-
-----BEGIN CERTIFICATE-----
|
40
|
-
MIIFMDCCBBigAwIBAgIQBAkYG1/Vu2Z1U0O1b5VQCDANBgkqhkiG9w0BAQsFADBl
|
41
|
-
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
|
42
|
-
d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
|
43
|
-
b3QgQ0EwHhcNMTMxMDIyMTIwMDAwWhcNMjgxMDIyMTIwMDAwWjByMQswCQYDVQQG
|
44
|
-
EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl
|
45
|
-
cnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFzc3VyZWQgSUQgQ29kZSBT
|
46
|
-
aWduaW5nIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+NOzHH8O
|
47
|
-
Ea9ndwfTCzFJGc/Q+0WZsTrbRPV/5aid2zLXcep2nQUut4/6kkPApfmJ1DcZ17aq
|
48
|
-
8JyGpdglrA55KDp+6dFn08b7KSfH03sjlOSRI5aQd4L5oYQjZhJUM1B0sSgmuyRp
|
49
|
-
wsJS8hRniolF1C2ho+mILCCVrhxKhwjfDPXiTWAYvqrEsq5wMWYzcT6scKKrzn/p
|
50
|
-
fMuSoeU7MRzP6vIK5Fe7SrXpdOYr/mzLfnQ5Ng2Q7+S1TqSp6moKq4TzrGdOtcT3
|
51
|
-
jNEgJSPrCGQ+UpbB8g8S9MWOD8Gi6CxR93O8vYWxYoNzQYIH5DiLanMg0A9kczye
|
52
|
-
n6Yzqf0Z3yWT0QIDAQABo4IBzTCCAckwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNV
|
53
|
-
HQ8BAf8EBAMCAYYwEwYDVR0lBAwwCgYIKwYBBQUHAwMweQYIKwYBBQUHAQEEbTBr
|
54
|
-
MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQwYIKwYBBQUH
|
55
|
-
MAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJ
|
56
|
-
RFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2lj
|
57
|
-
ZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6
|
58
|
-
Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcmww
|
59
|
-
TwYDVR0gBEgwRjA4BgpghkgBhv1sAAIEMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8v
|
60
|
-
d3d3LmRpZ2ljZXJ0LmNvbS9DUFMwCgYIYIZIAYb9bAMwHQYDVR0OBBYEFFrEuXsq
|
61
|
-
CqOl6nEDwGD5LfZldQ5YMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgP
|
62
|
-
MA0GCSqGSIb3DQEBCwUAA4IBAQA+7A1aJLPzItEVyCx8JSl2qB1dHC06GsTvMGHX
|
63
|
-
fgtg/cM9D8Svi/3vKt8gVTew4fbRknUPUbRupY5a4l4kgU4QpO4/cY5jDhNLrddf
|
64
|
-
RHnzNhQGivecRk5c/5CxGwcOkRX7uq+1UcKNJK4kxscnKqEpKBo6cSgCPC6Ro8Al
|
65
|
-
EeKcFEehemhor5unXCBc2XGxDI+7qPjFEmifz0DLQESlE/DmZAwlCEIysjaKJAL+
|
66
|
-
L3J+HNdJRZboWR3p+nRka7LrZkPas7CM1ekN3fYBIM6ZMWM9CBoYs4GbT8aTEAb8
|
67
|
-
B4H6i9r5gkn3Ym6hU/oSlBiFLpKR6mhsRDKyZqHnGKSaZFHv
|
68
|
-
-----END CERTIFICATE-----
|
69
|
-
- |
|
70
|
-
-----BEGIN CERTIFICATE-----
|
71
|
-
MIIFIzCCBAugAwIBAgIQCMePMbkSxvnPeJhYXIfaxzANBgkqhkiG9w0BAQsFADBy
|
72
|
-
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
|
73
|
-
d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFzc3VyZWQg
|
74
|
-
SUQgQ29kZSBTaWduaW5nIENBMB4XDTIwMTAwNzAwMDAwMFoXDTIzMTEwNjEyMDAw
|
75
|
-
MFowYDELMAkGA1UEBhMCVVMxFjAUBgNVBAgTDU1hc3NhY2h1c2V0dHMxDzANBgNV
|
76
|
-
BAcTBkJvc3RvbjETMBEGA1UEChMKUmFwaWQ3IExMQzETMBEGA1UEAxMKUmFwaWQ3
|
77
|
-
IExMQzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALNTz4zvAy7h/vQp
|
78
|
-
4dr1txXHlABAagkwYYwTMCtHs5PXsJITx/5SAjx5swuaLfze5kPBNF2YImvFlOXY
|
79
|
-
WaB+0PsOnXnaARsDZU683xFlj8izU6IN6VrAHzDLKFBzruJENrOJD/ikbEtbjO/q
|
80
|
-
gFbmS9J9v5ohG/pcRSS0t4ZPAwymf8eCp6QsvOKK/Aymp1RhlRaP8N6N5CIpkhz1
|
81
|
-
9p968iCE+DjOXVYxcWE+jE/7uB1dbgrXykNBujMSS3GULOvVEY28n6NCmrPlo23g
|
82
|
-
yRjYVJ2Vy14nBqnxDZ/yRIfWRVjWoT9TsAEbe9gY29oDpSCSs4wSmLQd5zGCpZ9h
|
83
|
-
r0HDFB8CAwEAAaOCAcUwggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZl
|
84
|
-
dQ5YMB0GA1UdDgQWBBTLBL7DTwumVEKtdCdpHVYMXOFeDzAOBgNVHQ8BAf8EBAMC
|
85
|
-
B4AwEwYDVR0lBAwwCgYIKwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDov
|
86
|
-
L2NybDMuZGlnaWNlcnQuY29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGG
|
87
|
-
L2h0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3Js
|
88
|
-
MEwGA1UdIARFMEMwNwYJYIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8v
|
89
|
-
d3d3LmRpZ2ljZXJ0LmNvbS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYw
|
90
|
-
JAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcw
|
91
|
-
AoZCaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3Vy
|
92
|
-
ZWRJRENvZGVTaWduaW5nQ0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQEL
|
93
|
-
BQADggEBAN+GL5/myPWg7oH4mVrG7/OhXF1MoYQF0ddaNiqaweEHMuKJBQCVZRbL
|
94
|
-
37HojoKXXv2yyRJBCeTB+ojrxX+5PdLVZa0ss7toWzJ2A1poPXZ1eZvm5xeFD32z
|
95
|
-
YQaTmmNWNI3PCDTyJ2PXUc+bDiNNwcZ7yc5o78UNRvp9Jxghya17Q76c9Ov9wvnv
|
96
|
-
dxxQKWGOQy0m4fBrkyjAyH9Djjn81RbQrqYgPuhd5nD0HjN3VUQLhQbIJrk9TVs0
|
97
|
-
EknWpNgVhohbot1lfVAMmIhdtOVaRVcQQixWPwprDj/ydB8ryDMDosIMcw+fkoXU
|
98
|
-
9GJsSaSRRYQ9UUkVL27b64okU8D48m8=
|
99
|
-
-----END CERTIFICATE-----
|
100
|
-
date: 2023-10-25 00:00:00.000000000 Z
|
41
|
+
date: 2023-11-13 00:00:00.000000000 Z
|
101
42
|
dependencies:
|
102
43
|
- !ruby/object:Gem::Dependency
|
103
44
|
name: redcarpet
|
metadata.gz.sig
CHANGED
Binary file
|