lib/ruby_smb/server/server_client/session_setup.rb
module RubySMB
class Server
class ServerClient
module SessionSetup
def do_session_setup_andx_smb1(request, session)
session_id = request.smb_header.uid
if session_id == 0
session_id = rand(1..0x10000)
session = @session_table[session_id] = Server::Session.new(session_id)
else
session = @session_table[session_id]
if session.nil?
response = SMB1::Packet::EmptyPacket.new
response.smb_header.nt_status = SMBError::STATUS_SMB_BAD_UID
return response
end
end
gss_result = process_gss(request.data_block.security_blob)
return if gss_result.nil?
response = SMB1::Packet::SessionSetupResponse.new
response.smb_header.pid_low = request.smb_header.pid_low
response.smb_header.uid = session_id
response.smb_header.mid = request.smb_header.mid
response.smb_header.nt_status = gss_result.nt_status.value
response.smb_header.flags.reply = true
response.smb_header.flags2.unicode = true
response.smb_header.flags2.extended_security = true
unless gss_result.buffer.nil?
response.parameter_block.security_blob_length = gss_result.buffer.length
response.data_block.security_blob = gss_result.buffer
end
if gss_result.nt_status == WindowsError::NTStatus::STATUS_SUCCESS
session.state = :valid
session.user_id = gss_result.identity
session.key = @gss_authenticator.session_key
end
response
end
alias :do_session_setup_smb1 :do_session_setup_andx_smb1
def do_logoff_andx_smb1(request, session)
# see: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-cifs/00fc0299-496c-4330-9089-67358994f272
@session_table.delete(request.smb_header.uid)
session.logoff!
response = SMB1::Packet::LogoffResponse.new
response
end
def do_session_setup_smb2(request, session)
@smb2_related_operations_state.delete(:session_id)
session_id = request.smb2_header.session_id
if session_id == 0
session_id = rand(1..0xfffffffe)
session = Session.new(session_id)
else
session = @session_table[session_id]
if session.nil?
response = SMB2::Packet::ErrorPacket.new
response.smb2_header.nt_status = WindowsError::NTStatus::STATUS_USER_SESSION_DELETED
return response
end
end
gss_result = process_gss(request.buffer)
return if gss_result.nil?
response = SMB2::Packet::SessionSetupResponse.new
response.smb2_header.nt_status = gss_result.nt_status.value
response.smb2_header.credits = 1
response.smb2_header.message_id = request.smb2_header.message_id
response.smb2_header.session_id = session_id
response.buffer = gss_result.buffer
update_preauth_hash(request) if @dialect == '0x0311'
if gss_result.nt_status == WindowsError::NTStatus::STATUS_SUCCESS
session.state = :valid
session.user_id = gss_result.identity
session.is_guest = !!gss_result.is_guest
session.key = @gss_authenticator.session_key
session.signing_required = request.security_mode.signing_required == 1 || (!session.is_guest && !session.is_anonymous)
response.smb2_header.credits = 32
@cipher_id = 0 if session.is_anonymous || session.is_guest # disable encryption for anonymous users and guest users which have a null session key
response.session_flags.encrypt_data = 1 unless @cipher_id == 0
response.session_flags.guest = session.is_guest
elsif gss_result.nt_status == WindowsError::NTStatus::STATUS_MORE_PROCESSING_REQUIRED && @dialect == '0x0311'
update_preauth_hash(response)
end
@session_table[session_id] = session
@smb2_related_operations_state[:session_id] = session_id
response
end
def do_logoff_smb2(request, session)
# see: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/a6fbc502-75a5-42ef-a88c-c67b44817850
@session_table.delete(session.id)
session.logoff!
response = SMB2::Packet::LogoffResponse.new
response
end
end
end
end
end