Class: RubySMB::Gss::Provider::NTLM

Inherits:
Base
  • Object
show all
Includes:
NTLM
Defined in:
lib/ruby_smb/gss/provider/ntlm.rb

Overview

A GSS provider that authenticates clients via the NT LAN Manager (NTLM) Security Support Provider (NTLMSSP) protocol.

Defined Under Namespace

Classes: Account, Authenticator

Constant Summary

Constants included from NTLM

NTLM::DEFAULT_CLIENT_FLAGS, NTLM::NEGOTIATE_FLAGS

Instance Attribute Summary collapse

Attributes inherited from Base

#allow_anonymous, #allow_guests

Instance Method Summary collapse

Methods included from NTLM

ntlmv2_hash

Constructor Details

#initialize(allow_anonymous: false, allow_guests: false, default_domain: 'WORKGROUP') ⇒ NTLM

Returns a new instance of NTLM.

Parameters:

  • allow_anonymous (Boolean) (defaults to: false)

    whether or not to allow anonymous authentication attempts

  • default_domain (String) (defaults to: 'WORKGROUP')

    the default domain to use for authentication, unless specified 'WORKGROUP' will be used

Raises:

  • (ArgumentError)


267
268
269
270
271
272
273
274
275
276
277
278
# File 'lib/ruby_smb/gss/provider/ntlm.rb', line 267

def initialize(allow_anonymous: false, allow_guests: false, default_domain: 'WORKGROUP')
  raise ArgumentError, 'Must specify a default domain' unless default_domain

  @allow_anonymous = allow_anonymous
  @allow_guests = allow_guests
  @default_domain = default_domain
  @accounts = []
  @generate_server_challenge = -> { SecureRandom.bytes(8) }

  @dns_domain = @netbios_domain = 'LOCALDOMAIN'
  @dns_hostname = @netbios_hostname = 'LOCALHOST'
end

Instance Attribute Details

#default_domainObject (readonly)

The default domain value to use for accounts which do not have one specified or use the special '.' value.



331
332
333
# File 'lib/ruby_smb/gss/provider/ntlm.rb', line 331

def default_domain
  @default_domain
end

#dns_domainObject

Returns the value of attribute dns_domain.



333
334
335
# File 'lib/ruby_smb/gss/provider/ntlm.rb', line 333

def dns_domain
  @dns_domain
end

#dns_hostnameObject

Returns the value of attribute dns_hostname.



333
334
335
# File 'lib/ruby_smb/gss/provider/ntlm.rb', line 333

def dns_hostname
  @dns_hostname
end

#netbios_domainObject

Returns the value of attribute netbios_domain.



333
334
335
# File 'lib/ruby_smb/gss/provider/ntlm.rb', line 333

def netbios_domain
  @netbios_domain
end

#netbios_hostnameObject

Returns the value of attribute netbios_hostname.



333
334
335
# File 'lib/ruby_smb/gss/provider/ntlm.rb', line 333

def netbios_hostname
  @netbios_hostname
end

Instance Method Details

#generate_server_challenge(&block) ⇒ String

Generate the 8-byte server challenge. If a block is specified, it's used as the challenge generation routine and should return an 8-byte value.

Returns:

  • (String)

    an 8-byte challenge value



285
286
287
288
289
290
291
# File 'lib/ruby_smb/gss/provider/ntlm.rb', line 285

def generate_server_challenge(&block)
  if block.nil?
    @generate_server_challenge.call
  else
    @generate_server_challenge = block
  end
end

#get_account(username, domain: nil) ⇒ Account?

Lookup and return an account based on the username and optionally, the domain. If no domain is specified or or it is the special value '.', the default domain will be used. The username and domain values are case insensitive.

Parameters:

  • username (String)

    the username of the account to fetch.

  • domain (String, nil) (defaults to: nil)

    the domain in which the account to fetch exists.

Returns:

  • (Account, nil)

    the account if it was found



307
308
309
310
311
312
313
314
315
316
# File 'lib/ruby_smb/gss/provider/ntlm.rb', line 307

def (username, domain: nil)
  # the username and password values should use the native encoding for the comparison in the #find operation
  username = username.downcase
  domain = @default_domain if domain.nil? || domain == '.'.encode(domain.encoding)
  domain = domain.downcase
  @accounts.find do ||
    RubySMB::Utils.safe_encode(.username, username.encoding).downcase == username &&
      RubySMB::Utils.safe_encode(.domain, domain.encoding).downcase == domain
  end
end

#new_authenticator(server_client) ⇒ Object



293
294
295
296
297
# File 'lib/ruby_smb/gss/provider/ntlm.rb', line 293

def new_authenticator(server_client)
  # build and return an instance that can process and track stateful information for a particular connection but
  # that's backed by this particular provider
  Authenticator.new(self, server_client)
end

#put_account(username, password, domain: nil) ⇒ Object

Add an account to the database.

Parameters:

  • username (String)

    the username of the account to add

  • password (String)

    either the plaintext password or the NTLM hash of the account to add

  • domain (String) (defaults to: nil)

    the domain of the account to add, if not specified, the @default_domain will be used



324
325
326
327
# File 'lib/ruby_smb/gss/provider/ntlm.rb', line 324

def (username, password, domain: nil)
  domain = @default_domain if domain.nil? || domain == '.'.encode(domain.encoding)
  @accounts << Account.new(username, password, domain)
end