Switch to an enum option for the signing
This commit is contained in:
parent
6d915dbb55
commit
69d603e6fc
|
@ -196,7 +196,6 @@ Module options (auxiliary/gather/ldap_esc_vulnerable_cert_finder):
|
|||
DOMAIN no The domain to authenticate to
|
||||
PASSWORD no The password to authenticate with
|
||||
REPORT_NONENROLLABLE false yes Report nonenrollable certificate templates
|
||||
REQUIRE_SIGNING true yes Use signed and encrypted LDAP
|
||||
RHOSTS yes The target host(s), see https://github.com/rapid7/metasploit
|
||||
-framework/wiki/Using-Metasploit
|
||||
RPORT 389 yes The target port
|
||||
|
|
|
@ -107,16 +107,15 @@ msf6 auxiliary(admin/ldap/shadow_credentials) > show options
|
|||
|
||||
Module options (auxiliary/admin/ldap/shadow_credentials):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
DOMAIN no The domain to authenticate to
|
||||
PASSWORD no The password to authenticate with
|
||||
REQUIRE_SIGNING true yes Use signed and encrypted LDAP
|
||||
RHOSTS yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
|
||||
RPORT 389 yes The target port
|
||||
SSL false no Enable SSL on the LDAP connection
|
||||
TARGET_USER yes The target to write to
|
||||
USERNAME no The username to authenticate with
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
DOMAIN no The domain to authenticate to
|
||||
PASSWORD no The password to authenticate with
|
||||
RHOSTS yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
|
||||
RPORT 389 yes The target port
|
||||
SSL false no Enable SSL on the LDAP connection
|
||||
TARGET_USER yes The target to write to
|
||||
USERNAME no The username to authenticate with
|
||||
|
||||
|
||||
When ACTION is REMOVE:
|
||||
|
@ -262,4 +261,4 @@ msf6 auxiliary(admin/ldap/shadow_credentials) > run rhost=20.92.148.129 username
|
|||
[*] Certificate stored at: /home/user/.msf4/loot/20240404122240_default_20.92.148.129_windows.ad.cs_785877.pfx
|
||||
[+] Successfully updated the msDS-KeyCredentialLink attribute; certificate with device ID 1107833b-0eb6-0477-a7c6-3590b326851a
|
||||
[*] Auxiliary module execution completed
|
||||
```
|
||||
```
|
||||
|
|
|
@ -60,18 +60,17 @@ msf5 auxiliary(admin/ldap/vmware_vcenter_vmdir_auth_bypass) > options
|
|||
|
||||
Module options (auxiliary/admin/ldap/vmware_vcenter_vmdir_auth_bypass):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
BASE_DN no LDAP base DN if you already have it
|
||||
DOMAIN no The domain to authenticate to
|
||||
NEW_PASSWORD no Password of admin user to add
|
||||
NEW_USERNAME no Username of admin user to add
|
||||
PASSWORD no The password to authenticate with
|
||||
REQUIRE_SIGNING true yes Use signed and encrypted LDAP
|
||||
RHOSTS yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
|
||||
RPORT 636 yes The target port
|
||||
SSL true no Enable SSL on the LDAP connection
|
||||
USERNAME no The username to authenticate with
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
BASE_DN no LDAP base DN if you already have it
|
||||
DOMAIN no The domain to authenticate to
|
||||
NEW_PASSWORD no Password of admin user to add
|
||||
NEW_USERNAME no Username of admin user to add
|
||||
PASSWORD no The password to authenticate with
|
||||
RHOSTS yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
|
||||
RPORT 636 yes The target port
|
||||
SSL true no Enable SSL on the LDAP connection
|
||||
USERNAME no The username to authenticate with
|
||||
|
||||
|
||||
Auxiliary action:
|
||||
|
|
|
@ -116,7 +116,6 @@ Module options (auxiliary/gather/ldap_esc_vulnerable_cert_finder):
|
|||
BIND_DN DAFOREST\Administrator no The username to authenticate to LDAP server
|
||||
BIND_PW theAdmin123 no Password for the BIND_DN
|
||||
REPORT_NONENROLLABLE false yes Report nonenrollable certificate templates
|
||||
REQUIRE_SIGNING true yes Use signed and encrypted LDAP
|
||||
RHOSTS 172.26.104.157 yes The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Using-Metasploit
|
||||
RPORT 389 yes The target port
|
||||
SSL false no Enable SSL on the LDAP connection
|
||||
|
|
|
@ -28,27 +28,25 @@ msf5 auxiliary(gather/ldap_hashdump) > options
|
|||
|
||||
Module options (auxiliary/gather/ldap_hashdump):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
BASE_DN no LDAP base DN if you already have it
|
||||
DOMAIN no The domain to authenticate to
|
||||
MAX_LOOT no Maximum number of LDAP entries to loot
|
||||
PASSWORD no The password to authenticate with
|
||||
PASS_ATTR userPassword, sambantpassword, sambalmpassword, mailu yes LDAP attribute, that contains password hashes
|
||||
serpassword, password, pwdhistory, passwordhistory, c
|
||||
learpassword
|
||||
READ_TIMEOUT 600 no LDAP read timeout in seconds
|
||||
REQUIRE_SIGNING true yes Use signed and encrypted LDAP
|
||||
RHOSTS 127.0.0.1 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.ht
|
||||
ml
|
||||
RPORT 1389 yes The target port
|
||||
SSL true no Enable SSL on the LDAP connection
|
||||
THREADS 1 yes The number of concurrent threads (max one per host)
|
||||
USERNAME no The username to authenticate with
|
||||
USER_ATTR dn no LDAP attribute(s), that contains username
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
BASE_DN no LDAP base DN if you already have it]
|
||||
DOMAIN no The domain to authenticate to
|
||||
MAX_LOOT no Maximum number of LDAP entries to loot
|
||||
PASSWORD no The password to authenticate with
|
||||
PASS_ATTR userPassword, sambantpassword, sambalmpassword, mailu yes LDAP attribute, that contains password hashes
|
||||
serpassword, password, pwdhistory, passwordhistory, c
|
||||
learpassword
|
||||
READ_TIMEOUT 600 no LDAP read timeout in seconds
|
||||
RHOSTS 127.0.0.1 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.h
|
||||
tml
|
||||
RPORT 1389 yes The target port
|
||||
SSL true no Enable SSL on the LDAP connection
|
||||
THREADS 1 yes The number of concurrent threads (max one per host)
|
||||
USERNAME no The username to authenticate with
|
||||
USER_ATTR dn no LDAP attribute(s), that contains username
|
||||
|
||||
Auxiliary action:
|
||||
|
||||
Name Description
|
||||
---- -----------
|
||||
Dump Dump all LDAP data
|
||||
|
|
|
@ -215,16 +215,15 @@ msf6 auxiliary(gather/ldap_query) > show options
|
|||
|
||||
Module options (auxiliary/gather/ldap_query):
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
BASE_DN no LDAP base DN if you already have it
|
||||
DOMAIN no The domain to authenticate to
|
||||
OUTPUT_FORMAT table yes The output format to use (Accepted: csv, table, json)
|
||||
PASSWORD thePassword123 no The password to authenticate with
|
||||
REQUIRE_SIGNING true yes Use signed and encrypted LDAP
|
||||
RHOSTS 172.27.51.83 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
|
||||
RPORT 389 yes The target port
|
||||
SSL false no Enable SSL on the LDAP connection
|
||||
USERNAME normal@daforest.com no The username to authenticate with
|
||||
---- --------------- -------- -----------
|
||||
BASE_DN no LDAP base DN if you already have it
|
||||
DOMAIN no The domain to authenticate to
|
||||
OUTPUT_FORMAT table yes The output format to use (Accepted: csv, table, json)
|
||||
PASSWORD thePassword123 no The password to authenticate with
|
||||
RHOSTS 172.27.51.83 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
|
||||
RPORT 389 yes The target port
|
||||
SSL false no Enable SSL on the LDAP connection
|
||||
USERNAME normal@daforest.com no The username to authenticate with
|
||||
|
||||
|
||||
When ACTION is RUN_QUERY_FILE:
|
||||
|
@ -242,7 +241,6 @@ Module options (auxiliary/gather/ldap_query):
|
|||
QUERY_FILTER no Filter to send to the target LDAP server to perform the query
|
||||
|
||||
Auxiliary action:
|
||||
|
||||
Name Description
|
||||
---- -----------
|
||||
RUN_QUERY_FILE Execute a custom set of LDAP queries from the JSON or YAML file specified by QUERY_FILE.
|
||||
|
|
|
@ -39,18 +39,16 @@ If you already have the LDAP base DN, you may set it in this option.
|
|||
msf5 > use auxiliary/gather/vmware_vcenter_vmdir_ldap
|
||||
msf5 auxiliary(gather/vmware_vcenter_vmdir_ldap) > options
|
||||
|
||||
Module options (auxiliary/gather/vmware_vcenter_vmdir_ldap):
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
BASE_DN no LDAP base DN if you already have it
|
||||
DOMAIN no The domain to authenticate to
|
||||
PASSWORD no The password to authenticate with
|
||||
RHOSTS yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
|
||||
RPORT 636 yes The target port
|
||||
SSL true no Enable SSL on the LDAP connection
|
||||
USERNAME no The username to authenticate with
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
BASE_DN no LDAP base DN if you already have it
|
||||
DOMAIN no The domain to authenticate to
|
||||
PASSWORD no The password to authenticate with
|
||||
REQUIRE_SIGNING true yes Use signed and encrypted LDAP
|
||||
RHOSTS yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
|
||||
RPORT 636 yes The target port
|
||||
SSL true no Enable SSL on the LDAP connection
|
||||
USERNAME no The username to authenticate with
|
||||
|
||||
Auxiliary action:
|
||||
|
||||
|
|
|
@ -127,18 +127,16 @@ module Metasploit
|
|||
|
||||
case opts[:ldap_auth]
|
||||
when Msf::Exploit::Remote::AuthOption::SCHANNEL
|
||||
raise Msf::ValidationError, 'The SSL option must be enabled when using SCHANNEL authentication.' unless ssl
|
||||
|
||||
connect_opts.merge!(ldap_auth_opts_schannel(opts))
|
||||
connect_opts.merge!(ldap_auth_opts_schannel(opts, ssl))
|
||||
when Msf::Exploit::Remote::AuthOption::KERBEROS
|
||||
connect_opts.merge!(ldap_auth_opts_kerberos(opts))
|
||||
connect_opts.merge!(ldap_auth_opts_kerberos(opts, ssl))
|
||||
when Msf::Exploit::Remote::AuthOption::NTLM
|
||||
connect_opts.merge!(ldap_auth_opts_ntlm(opts))
|
||||
connect_opts.merge!(ldap_auth_opts_ntlm(opts, ssl))
|
||||
when Msf::Exploit::Remote::AuthOption::PLAINTEXT
|
||||
connect_opts.merge!(ldap_auth_opts_plaintext(opts))
|
||||
when Msf::Exploit::Remote::AuthOption::AUTO
|
||||
if opts[:username].present? && opts[:domain].present?
|
||||
connect_opts.merge!(ldap_auth_opts_ntlm(opts))
|
||||
connect_opts.merge!(ldap_auth_opts_ntlm(opts, ssl))
|
||||
elsif opts[:username].present?
|
||||
connect_opts.merge!(ldap_auth_opts_plaintext(opts))
|
||||
end
|
||||
|
@ -149,15 +147,15 @@ module Metasploit
|
|||
|
||||
private
|
||||
|
||||
def ldap_auth_opts_kerberos(opts)
|
||||
def ldap_auth_opts_kerberos(opts, ssl)
|
||||
auth_opts = {}
|
||||
raise Msf::ValidationError, 'The Ldap::Rhostname option is required when using Kerberos authentication.' if opts[:ldap_rhostname].blank?
|
||||
raise Msf::ValidationError, 'The LDAP::Rhostname option is required when using Kerberos authentication.' if opts[:ldap_rhostname].blank?
|
||||
raise Msf::ValidationError, 'The DOMAIN option is required when using Kerberos authentication.' if opts[:domain].blank?
|
||||
|
||||
offered_etypes = Msf::Exploit::Remote::AuthOption.as_default_offered_etypes(opts[:ldap_krb_offered_enc_types])
|
||||
raise Msf::ValidationError, 'At least one encryption type is required when using Kerberos authentication.' if offered_etypes.empty?
|
||||
|
||||
use_gss_checksum = opts[:should_encrypt]
|
||||
sign_and_seal = opts.fetch(:sign_and_seal, !ssl)
|
||||
kerberos_authenticator = Msf::Exploit::Remote::Kerberos::ServiceAuthenticator::LDAP.new(
|
||||
host: opts[:domain_controller_rhost].blank? ? nil : opts[:domain_controller_rhost],
|
||||
hostname: opts[:ldap_rhostname],
|
||||
|
@ -170,7 +168,7 @@ module Metasploit
|
|||
ticket_storage: opts[:kerberos_ticket_storage],
|
||||
offered_etypes: offered_etypes,
|
||||
mutual_auth: true,
|
||||
use_gss_checksum: use_gss_checksum
|
||||
use_gss_checksum: sign_and_seal
|
||||
)
|
||||
|
||||
encryptor = SpnegoKerberosEncryptor.new(kerberos_authenticator)
|
||||
|
@ -184,14 +182,14 @@ module Metasploit
|
|||
challenge_response: true
|
||||
}
|
||||
|
||||
if opts[:should_encrypt]
|
||||
if sign_and_seal
|
||||
auth_opts[:auth][:auth_context_setup] = encryptor.method(:kerberos_setup)
|
||||
end
|
||||
|
||||
auth_opts
|
||||
end
|
||||
|
||||
def ldap_auth_opts_ntlm(opts)
|
||||
def ldap_auth_opts_ntlm(opts, ssl)
|
||||
auth_opts = {}
|
||||
flags = RubySMB::NTLM::NEGOTIATE_FLAGS[:UNICODE] |
|
||||
RubySMB::NTLM::NEGOTIATE_FLAGS[:REQUEST_TARGET] |
|
||||
|
@ -202,7 +200,8 @@ module Metasploit
|
|||
RubySMB::NTLM::NEGOTIATE_FLAGS[:TARGET_INFO] |
|
||||
RubySMB::NTLM::NEGOTIATE_FLAGS[:VERSION_INFO]
|
||||
|
||||
if opts[:should_encrypt]
|
||||
sign_and_seal = opts.fetch(:sign_and_seal, !ssl)
|
||||
if sign_and_seal
|
||||
flags = flags |
|
||||
RubySMB::NTLM::NEGOTIATE_FLAGS[:SIGN] |
|
||||
RubySMB::NTLM::NEGOTIATE_FLAGS[:SEAL] |
|
||||
|
@ -234,7 +233,7 @@ module Metasploit
|
|||
challenge_response: negotiate
|
||||
}
|
||||
|
||||
if opts[:should_encrypt]
|
||||
if sign_and_seal
|
||||
auth_opts[:auth][:auth_context_setup] = encryptor.method(:ntlm_setup)
|
||||
end
|
||||
|
||||
|
@ -243,6 +242,8 @@ module Metasploit
|
|||
|
||||
def ldap_auth_opts_plaintext(opts)
|
||||
auth_opts = {}
|
||||
raise Msf::ValidationError, 'Can not sign and seal when using Plaintext authentication.' if opts.fetch(:sign_and_seal, false)
|
||||
|
||||
auth_opts[:auth] = {
|
||||
method: :simple,
|
||||
username: opts[:username],
|
||||
|
@ -251,10 +252,12 @@ module Metasploit
|
|||
auth_opts
|
||||
end
|
||||
|
||||
def ldap_auth_opts_schannel(opts)
|
||||
def ldap_auth_opts_schannel(opts, ssl)
|
||||
auth_opts = {}
|
||||
pfx_path = opts[:ldap_cert_file]
|
||||
raise Msf::ValidationError, 'The LDAP::CertFile option is required when using SCHANNEL authentication.' if pfx_path.blank?
|
||||
raise Msf::ValidationError, 'The SSL option must be enabled when using Schannel authentication.' unless ssl
|
||||
raise Msf::ValidationError, 'The LDAP::CertFile option is required when using Schannel authentication.' if pfx_path.blank?
|
||||
raise Msf::ValidationError, 'Can not sign and seal when using Schannel authentication.' if opts.fetch(:sign_and_seal, false)
|
||||
|
||||
unless ::File.file?(pfx_path) && ::File.readable?(pfx_path)
|
||||
raise Msf::ValidationError, 'Failed to load the PFX certificate file. The path was not a readable file.'
|
||||
|
|
|
@ -32,8 +32,7 @@ module Msf
|
|||
OptBool.new('SSL', [false, 'Enable SSL on the LDAP connection', false]),
|
||||
Msf::OptString.new('DOMAIN', [false, 'The domain to authenticate to']),
|
||||
Msf::OptString.new('USERNAME', [false, 'The username to authenticate with'], aliases: ['BIND_DN']),
|
||||
Msf::OptString.new('PASSWORD', [false, 'The password to authenticate with'], aliases: ['BIND_PW']),
|
||||
OptBool.new('REQUIRE_SIGNING', [true, 'Use signed and encrypted LDAP', true])
|
||||
Msf::OptString.new('PASSWORD', [false, 'The password to authenticate with'], aliases: ['BIND_PW'])
|
||||
])
|
||||
|
||||
register_advanced_options(
|
||||
|
@ -42,7 +41,8 @@ module Msf
|
|||
*kerberos_storage_options(protocol: 'LDAP'),
|
||||
*kerberos_auth_options(protocol: 'LDAP', auth_methods: Msf::Exploit::Remote::AuthOption::LDAP_OPTIONS),
|
||||
Msf::OptPath.new('LDAP::CertFile', [false, 'The path to the PKCS12 (.pfx) certificate file to authenticate with'], conditions: ['LDAP::Auth', '==', Msf::Exploit::Remote::AuthOption::SCHANNEL]),
|
||||
OptFloat.new('LDAP::ConnectTimeout', [true, 'Timeout for LDAP connect', 10.0])
|
||||
OptFloat.new('LDAP::ConnectTimeout', [true, 'Timeout for LDAP connect', 10.0]),
|
||||
OptEnum.new('LDAP::Signing', [true, 'Use signed and sealed (encrypted) LDAP', 'auto', %w[ disabled auto required ]])
|
||||
]
|
||||
)
|
||||
end
|
||||
|
@ -80,26 +80,37 @@ module Msf
|
|||
password: datastore['PASSWORD'],
|
||||
domain: datastore['DOMAIN'],
|
||||
domain_controller_rhost: datastore['DomainControllerRhost'],
|
||||
should_encrypt: datastore['REQUIRE_SIGNING'],
|
||||
ldap_auth: datastore['LDAP::Auth'],
|
||||
ldap_cert_file: datastore['LDAP::CertFile'],
|
||||
ldap_rhostname: datastore['Ldap::Rhostname'],
|
||||
ldap_krb_offered_enc_types: datastore['Ldap::KrbOfferedEncryptionTypes'],
|
||||
ldap_krb5_cname: datastore['Ldap::Krb5Ccname'],
|
||||
ldap_rhostname: datastore['LDAP::Rhostname'],
|
||||
ldap_krb_offered_enc_types: datastore['LDAP::KrbOfferedEncryptionTypes'],
|
||||
ldap_krb5_cname: datastore['LDAP::Krb5Ccname'],
|
||||
proxies: datastore['Proxies'],
|
||||
framework_module: self
|
||||
}
|
||||
case datastore['LDAP::Signing']
|
||||
when 'required'
|
||||
opts[:sign_and_seal] = true
|
||||
when 'disabled'
|
||||
opts[:sign_and_seal] = false
|
||||
end
|
||||
|
||||
result = ldap_connect_opts(rhost, rport, datastore['LDAP::ConnectTimeout'], ssl: datastore['SSL'], opts: opts)
|
||||
begin
|
||||
result = ldap_connect_opts(rhost, rport, datastore['LDAP::ConnectTimeout'], ssl: datastore['SSL'], opts: opts)
|
||||
rescue Msf::ValidationError => e
|
||||
fail_with(Msf::Module::Failure::BadConfig, e.message)
|
||||
end
|
||||
|
||||
# Now that the options have been resolved (including auto possibly resolving to NTLM), check whether this is a valid config
|
||||
if result[:auth] &&
|
||||
result[:auth][:method] == :sasl &&
|
||||
result[:auth][:mechanism] == 'GSS-SPNEGO' &&
|
||||
datastore['SSL'] &&
|
||||
datastore['REQUIRE_SIGNING']
|
||||
# Domain Controllers don't seem to support signing and connection over SSL. Gotta pick one or the other.
|
||||
fail_with(Msf::Module::Failure::BadConfig, 'SSL not supported with signing. Set either SSL or REQUIRE_SIGNING, but not both.')
|
||||
if result[:auth] && datastore['LDAP::Signing'] == 'required'
|
||||
unless (result[:auth][:method] == :sasl && result[:auth][:mechanism] == 'GSS-SPNEGO')
|
||||
fail_with(Msf::Module::Failure::BadConfig, 'The authentication configuration does not support signing. Change either LDAP::Auth or LDAP::Signing.')
|
||||
end
|
||||
|
||||
if result[:encryption]
|
||||
# Domain Controllers don't seem to support signing and connection over SSL. Gotta pick one or the other.
|
||||
fail_with(Msf::Module::Failure::BadConfig, 'SSL not supported with signing. Change either SSL or LDAP::Signing.')
|
||||
end
|
||||
end
|
||||
|
||||
result
|
||||
|
@ -257,7 +268,7 @@ module Msf
|
|||
fail_with(Msf::Module::Failure::NoTarget, 'Target does not support the simple authentication mechanism!')
|
||||
when 8
|
||||
signing_statement = ''
|
||||
signing_statement = 'May require LDAP signing to be enabled (`set REQUIRE_SIGNING true`). ' unless datastore['REQUIRE_SIGNING']
|
||||
signing_statement = 'May require LDAP signing to be enabled (`set LDAP::EnableSigning true`). ' unless datastore['LDAP::EnableSigning']
|
||||
|
||||
fail_with(Msf::Module::Failure::NoTarget, "Server requires a stronger form of authentication! #{signing_statement}The error was: #{bind_result[:error_message].strip}")
|
||||
when 14
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
module Rex::Proto::LDAP
|
||||
class LdapException < RuntimeError
|
||||
end
|
||||
end
|
||||
class LdapException < RuntimeError
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
module Rex::Proto::Sasl
|
||||
# Wrap the data in a SASL structure, per RFC 4422 (basically just prepends a big-endian encoded 32-bit integer representing the length)
|
||||
def wrap_sasl(data)
|
||||
length = [data.length].pack('N')
|
||||
# Wrap the data in a SASL structure, per RFC 4422 (basically just prepends a big-endian encoded 32-bit integer representing the length)
|
||||
def wrap_sasl(data)
|
||||
length = [data.length].pack('N')
|
||||
|
||||
length + data
|
||||
end
|
||||
|
||||
# Unwraps the data from a SASL structure, per RFC 4422
|
||||
def unwrap_sasl(data)
|
||||
length = data[0,4].unpack('N')[0]
|
||||
if length != data.length + 4
|
||||
raise ArgumentError.new('Invalid SASL structure')
|
||||
end
|
||||
length + data
|
||||
end
|
||||
|
||||
data[4,length]
|
||||
# Unwraps the data from a SASL structure, per RFC 4422
|
||||
def unwrap_sasl(data)
|
||||
length = data[0,4].unpack('N')[0]
|
||||
if length != data.length + 4
|
||||
raise ArgumentError.new('Invalid SASL structure')
|
||||
end
|
||||
end
|
||||
|
||||
data[4,length]
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue