Module: RubySMB::Gss
- Defined in:
- lib/ruby_smb/gss.rb,
lib/ruby_smb/gss/provider.rb,
lib/ruby_smb/gss/provider/ntlm.rb,
lib/ruby_smb/gss/provider/multi.rb,
lib/ruby_smb/gss/provider/kerberos.rb,
lib/ruby_smb/gss/spnego_neg_token_init.rb,
lib/ruby_smb/gss/spnego_neg_token_targ.rb,
lib/ruby_smb/gss/provider/authenticator.rb
Overview
module containing methods required for using the GSS-API for Secure Protected Negotiation(SPNEGO) in SMB Authentication.
Defined Under Namespace
Modules: Provider Classes: ContextFlags, GeneralString, MechType, MechTypeList, NegHints, NegTokenInit, SpnegoNegTokenInit, SpnegoNegTokenTarg
Constant Summary collapse
- OID_SPNEGO =
OpenSSL::ASN1::ObjectId.new('1.3.6.1.5.5.2')
- OID_NEGOEX =
OpenSSL::ASN1::ObjectId.new('1.3.6.1.4.1.311.2.2.30')
- OID_NTLMSSP =
OpenSSL::ASN1::ObjectId.new('1.3.6.1.4.1.311.2.2.10')
- OID_KERBEROS_5 =
The Kerberos v5 GSS-API mechanism (RFC 4121). Microsoft's SPNEGO implementation also uses a legacy OID that differs by a single arc, and clients may offer or select either, so both are defined here.
OpenSSL::ASN1::ObjectId.new('1.2.840.113554.1.2.2')
- OID_MICROSOFT_KERBEROS_5 =
OpenSSL::ASN1::ObjectId.new('1.2.840.48018.1.2.2')
Class Method Summary collapse
-
.asn1dig(asn, *path) ⇒ OpenSSL::ASN1::Sequence?
Allow safe navigation of a decoded ASN.1 data structure.
-
.asn1encode(str = '') ⇒ Object
Cargo culted from Rex.
-
.gss_neg_token_init(mech_types) ⇒ String
Build the SPNEGO NegTokenInit that a server sends to advertise the authentication mechanisms it supports, per RFC 4178 section 4.2.1.
-
.gss_type1(type1) ⇒ Object
Create a GSS Security Blob of an NTLM Type 1 Message.
-
.gss_type2(type2) ⇒ Object
Create a GSS Security Blob of an NTLM Type 2 Message.
-
.gss_type3(type3) ⇒ Object
Create a GSS Security Blob of an NTLM Type 3 Message.
Class Method Details
.asn1dig(asn, *path) ⇒ OpenSSL::ASN1::Sequence?
Allow safe navigation of a decoded ASN.1 data structure. Similar to Ruby's builtin Hash#dig method but using the #value attribute of each ASN object.
25 26 27 28 29 30 31 32 |
# File 'lib/ruby_smb/gss.rb', line 25 def self.asn1dig(asn, *path) path.each do |part| return nil unless asn&.value asn = asn.value[part] end asn end |
.asn1encode(str = '') ⇒ Object
Document these magic numbers
Cargo culted from Rex. Hacked Together ASN1 encoding that works for our GSS purposes
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/ruby_smb/gss.rb', line 36 def self.asn1encode(str = '') # If the high bit of the first byte is 1, it contains the number of # length bytes that follow case str.length when 0..0x7F encoded_string = [str.length].pack('C') + str when 0x80..0xFF encoded_string = [0x81, str.length].pack('CC') + str when 0x100..0xFFFF encoded_string = [0x82, str.length].pack('Cn') + str when 0x10000..0xffffff encoded_string = [0x83, str.length >> 16, str.length & 0xFFFF].pack('CCn') + str when 0x1000000..0xffffffff encoded_string = [0x84, str.length].pack('CN') + str else raise RubySMB::Error::ASN1Encoding, "Source string is too long. Size is #{str.length}" end encoded_string end |
.gss_neg_token_init(mech_types) ⇒ String
Build the SPNEGO NegTokenInit that a server sends to advertise the authentication mechanisms it supports, per RFC 4178 section 4.2.1.
The mechTypes list is supplied by the caller so that it reflects every mechanism the server actually offers, rather than being fixed to a single mechanism by whichever provider happens to build the token.
66 67 68 69 70 |
# File 'lib/ruby_smb/gss.rb', line 66 def self.gss_neg_token_init(mech_types) raise ArgumentError, 'at least one mechanism must be advertised' if mech_types.nil? || mech_types.empty? SpnegoNegTokenInit.build(mech_types) end |
.gss_type1(type1) ⇒ Object
Create a GSS Security Blob of an NTLM Type 1 Message.
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/ruby_smb/gss.rb', line 73 def self.gss_type1(type1) OpenSSL::ASN1::ASN1Data.new([ OID_SPNEGO, OpenSSL::ASN1::ASN1Data.new([ OpenSSL::ASN1::Sequence.new([ OpenSSL::ASN1::ASN1Data.new([ OpenSSL::ASN1::Sequence.new([ OID_NTLMSSP ]) ], 0, :CONTEXT_SPECIFIC), OpenSSL::ASN1::ASN1Data.new([ OpenSSL::ASN1::OctetString.new(type1) ], 2, :CONTEXT_SPECIFIC) ]) ], 0, :CONTEXT_SPECIFIC) ], 0, :APPLICATION).to_der end |
.gss_type2(type2) ⇒ Object
Create a GSS Security Blob of an NTLM Type 2 Message.
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/ruby_smb/gss.rb', line 92 def self.gss_type2(type2) OpenSSL::ASN1::ASN1Data.new([ OpenSSL::ASN1::Sequence.new([ OpenSSL::ASN1::ASN1Data.new([ OpenSSL::ASN1::Enumerated.new(OpenSSL::BN.new(1)) ], 0, :CONTEXT_SPECIFIC), OpenSSL::ASN1::ASN1Data.new([ OID_NTLMSSP ], 1, :CONTEXT_SPECIFIC), OpenSSL::ASN1::ASN1Data.new([ OpenSSL::ASN1::OctetString.new(type2) ], 2, :CONTEXT_SPECIFIC) ]) ], 1, :CONTEXT_SPECIFIC).to_der end |
.gss_type3(type3) ⇒ Object
Create a GSS Security Blob of an NTLM Type 3 Message.
109 110 111 112 113 114 115 116 117 |
# File 'lib/ruby_smb/gss.rb', line 109 def self.gss_type3(type3) OpenSSL::ASN1::ASN1Data.new([ OpenSSL::ASN1::Sequence.new([ OpenSSL::ASN1::ASN1Data.new([ OpenSSL::ASN1::OctetString.new(type3) ], 2, :CONTEXT_SPECIFIC) ]) ], 1, :CONTEXT_SPECIFIC).to_der end |