Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/lib/rex/proto/kerberos/model/kdc_request_body.rb
Views: 11766
# -*- coding: binary -*-12module Rex3module Proto4module Kerberos5module Model6# This class provides a representation of a Kerberos KDC-REQ-BODY (request body) data7# definition8# https://datatracker.ietf.org/doc/html/rfc4120#section-5.4.19# KDC-REQ-BODY ::= SEQUENCE {10# kdc-options [0] KDCOptions,11# cname [1] PrincipalName OPTIONAL12# -- Used only in AS-REQ --,13# realm [2] Realm14# -- Server's realm15# -- Also client's in AS-REQ --,16# sname [3] PrincipalName OPTIONAL,17# from [4] KerberosTime OPTIONAL,18# till [5] KerberosTime,19# rtime [6] KerberosTime OPTIONAL,20# nonce [7] UInt32,21# etype [8] SEQUENCE OF Int32 -- EncryptionType22# -- in preference order --,23# addresses [9] HostAddresses OPTIONAL,24# enc-authorization-data [10] EncryptedData OPTIONAL25# -- AuthorizationData --,26# additional-tickets [11] SEQUENCE OF Ticket OPTIONAL27# -- NOTE: not empty28# }29class KdcRequestBody < Element30# @!attribute options31# @return [Integer] The ticket flags32attr_accessor :options33# @!attribute cname34# @return [Rex::Proto::Kerberos::Model::PrincipalName] The name part of the client's principal identifier35attr_accessor :cname36# @!attribute realm37# @return [String] The realm part of the server's principal identifier38attr_accessor :realm39# @!attribute sname40# @return [Rex::Proto::Kerberos::Model::PrincipalName] The name part of the server's identity41attr_accessor :sname42# @!attribute from43# @return [Time] Start time when the ticket is to be postdated44attr_accessor :from45# @!attribute till46# @return [Time] Expiration date requested by the client47attr_accessor :till48# @!attribute rtime49# @return [Time] Optional requested renew-till time50attr_accessor :rtime51# @!attribute nonce52# @return [Integer] random number53attr_accessor :nonce54# @!attribute addresses55# @return [Array<Rex::Proto::Kerberos::Model::HostAddress>,nil] A list of addresses from which the requested ticket is valid56attr_accessor :addresses57# @!attribute etype58# @return [Array<Integer>] The desired encryption algorithm to be used in the response59attr_accessor :etype60# @!attribute enc_auth_data61# @return [Rex::Proto::Kerberos::Model::EncryptedData] An encoding of the desired authorization-data encrypted62attr_accessor :enc_auth_data63# @!attribute additional_tickets64# @return [Array<Rex::Proto::Kerberos::Model::EncryptedData>] Additional tickets65attr_accessor :additional_tickets6667# Decodes the Rex::Proto::Kerberos::Model::KdcRequestBody attributes from input68#69# @param input [String, OpenSSL::ASN1::Sequence] the input to decode from70# @return [self] if decoding succeeds71# @raise [Rex::Proto::Kerberos::Model::Error::KerberosDecodingError] if decoding doesn't succeed72def decode(input)73case input74when String75decode_string(input)76when OpenSSL::ASN1::Sequence77decode_asn1(input)78else79raise ::Rex::Proto::Kerberos::Model::Error::KerberosDecodingError, 'Failed to decode KdcRequestBody, invalid input'80end8182self83end8485# Encodes the Rex::Proto::Kerberos::Model::KdcRequestBody into an ASN.1 String86#87# @return [String]88def encode89elems = []9091elems << OpenSSL::ASN1::ASN1Data.new([encode_options], 0, :CONTEXT_SPECIFIC) if options92elems << OpenSSL::ASN1::ASN1Data.new([encode_cname], 1, :CONTEXT_SPECIFIC) if cname93elems << OpenSSL::ASN1::ASN1Data.new([encode_realm], 2, :CONTEXT_SPECIFIC) if realm94elems << OpenSSL::ASN1::ASN1Data.new([encode_sname], 3, :CONTEXT_SPECIFIC) if sname95elems << OpenSSL::ASN1::ASN1Data.new([encode_from], 4, :CONTEXT_SPECIFIC) if from96elems << OpenSSL::ASN1::ASN1Data.new([encode_till], 5, :CONTEXT_SPECIFIC) if till97elems << OpenSSL::ASN1::ASN1Data.new([encode_rtime], 6, :CONTEXT_SPECIFIC) if rtime98elems << OpenSSL::ASN1::ASN1Data.new([encode_nonce], 7, :CONTEXT_SPECIFIC) if nonce99elems << OpenSSL::ASN1::ASN1Data.new([encode_etype], 8, :CONTEXT_SPECIFIC) if etype100elems << OpenSSL::ASN1::ASN1Data.new([encode_addresses], 9, :CONTEXT_SPECIFIC) if addresses&.any?101elems << OpenSSL::ASN1::ASN1Data.new([encode_enc_auth_data], 10, :CONTEXT_SPECIFIC) if enc_auth_data102elems << OpenSSL::ASN1::ASN1Data.new([encode_additional_tickets], 11, :CONTEXT_SPECIFIC) if additional_tickets103104seq = OpenSSL::ASN1::Sequence.new(elems)105106seq.to_der107end108109# Makes a checksum from the Rex::Proto::Kerberos::Model::KdcRequestBody110#111# @param etype [Integer] the crypto schema to checksum112# @param key [String] the key used as the HMAC secret (applicable to most but not all checksum algorithms)113# @return [String] the checksum114# @raise [NotImplementedError] if the encryption schema isn't supported115def checksum(etype, key, key_usage)116data = self.encode117checksummer = Rex::Proto::Kerberos::Crypto::Checksum::from_checksum_type(etype)118checksummer.checksum(key, key_usage, data)119end120121private122123# Encodes the options124#125# @return [OpenSSL::ASN1::BitString]126def encode_options127OpenSSL::ASN1::BitString.new([options.to_i].pack('N'))128end129130# Encodes the cname131#132# @return [String]133def encode_cname134cname.encode135end136137# Encodes the realm138#139# @return [OpenSSL::ASN1::GeneralString]140def encode_realm141OpenSSL::ASN1::GeneralString.new(realm)142end143144# Encodes the sname145#146# @return [String]147def encode_sname148sname.encode149end150151# Encodes the from152#153# @return [OpenSSL::ASN1::GeneralizedTime]154def encode_from155OpenSSL::ASN1::GeneralizedTime.new(from)156end157158# Encodes the till159#160# @return [OpenSSL::ASN1::GeneralizedTime]161def encode_till162OpenSSL::ASN1::GeneralizedTime.new(till)163end164165# Encodes the rtime166#167# @return [OpenSSL::ASN1::GeneralizedTime]168def encode_rtime169OpenSSL::ASN1::GeneralizedTime.new(rtime)170end171172# Encodes the nonce173#174# @return [OpenSSL::ASN1::Integer]175def encode_nonce176bn = OpenSSL::BN.new(nonce.to_s)177int = OpenSSL::ASN1::Integer.new(bn)178179int180end181182# Encodes the etype183#184# @return [OpenSSL::ASN1::Sequence]185def encode_etype186encoded_types = []187etype.each do |member|188bn = OpenSSL::BN.new(member.to_s)189int = OpenSSL::ASN1::Integer.new(bn)190encoded_types << int191end192193OpenSSL::ASN1::Sequence.new(encoded_types)194end195196# Encodes the list of addresses from which the requested ticket is valid197#198# @return [OpenSSL::ASN1::Sequence]199def encode_addresses200encoded_addresses = []201202addresses.each do |address|203encoded_addresses << address.to_asn1204end205206OpenSSL::ASN1::Sequence.new(encoded_addresses)207end208209# Encodes the enc_auth_data210#211# @return [String]212def encode_enc_auth_data213enc_auth_data.encode214end215216# Encodes the additional_tickets217#218# @return [OpenSSL::ASN1::Sequence]219def encode_additional_tickets220encoded_tickets = []221additional_tickets.each do |ticket|222encoded_tickets << ticket.encode223end224225OpenSSL::ASN1::Sequence.new(encoded_tickets)226end227228# Decodes a Rex::Proto::Kerberos::Model::KdcRequestBody from an String229#230# @param input [String] the input to decode from231# @raise [Rex::Proto::Kerberos::Model::Error::KerberosDecodingError] if decoding doesn't succeed232def decode_string(input)233asn1 = OpenSSL::ASN1.decode(input)234235decode_asn1(asn1)236rescue OpenSSL::ASN1::ASN1Error237raise Rex::Proto::Kerberos::Model::Error::KerberosDecodingError238end239240# Decodes a Rex::Proto::Kerberos::Model::KdcRequestBody from an241# OpenSSL::ASN1::Sequence242#243# @param input [OpenSSL::ASN1::Sequence] the input to decode from244# @raise [Rex::Proto::Kerberos::Model::Error::KerberosDecodingError] if decoding doesn't succeed245def decode_asn1(input)246seq_values = input.value247248seq_values.each do |val|249case val.tag250when 0251self.options = decode_options(val)252when 1253self.cname = decode_cname(val)254when 2255self.realm = decode_realm(val)256when 3257self.sname = decode_sname(val)258when 4259self.from = decode_from(val)260when 5261self.till = decode_till(val)262when 6263self.rtime = decode_rtime(val)264when 7265self.nonce = decode_nonce(val)266when 8267self.etype = decode_etype(val)268when 9269self.addresses = decode_addresses(val)270when 10271self.enc_auth_data = decode_enc_auth_data(val)272when 11273self.additional_tickets = decode_additional_tickets(val)274else275raise ::Rex::Proto::Kerberos::Model::Error::KerberosDecodingError, 'Failed to decode KdcRequestBody SEQUENCE'276end277end278end279280# Decodes the options field281#282# @param input [OpenSSL::ASN1::ASN1Data] the input to decode from283# @return [Integer]284def decode_options(input)285input.value[0].value.unpack('N')[0]286end287288# Decodes the cname field289#290# @param input [OpenSSL::ASN1::ASN1Data] the input to decode from291# @return [Rex::Proto::Kerberos::Model::PrincipalName]292def decode_cname(input)293Rex::Proto::Kerberos::Model::PrincipalName.decode(input.value[0])294end295296# Decodes the realm field297#298# @param input [OpenSSL::ASN1::ASN1Data] the input to decode from299# @return [String]300def decode_realm(input)301input.value[0].value302end303304# Decodes the sname field305#306# @param input [OpenSSL::ASN1::ASN1Data] the input to decode from307# @return [Rex::Proto::Kerberos::Model::PrincipalName]308def decode_sname(input)309Rex::Proto::Kerberos::Model::PrincipalName.decode(input.value[0])310end311312# Decodes the from field313#314# @param input [OpenSSL::ASN1::ASN1Data] the input to decode from315# @return [Time]316def decode_from(input)317input.value[0].value318end319320# Decodes the till field321#322# @param input [OpenSSL::ASN1::ASN1Data] the input to decode from323# @return [Time]324def decode_till(input)325input.value[0].value326end327328# Decodes the rtime field329#330# @param input [OpenSSL::ASN1::ASN1Data] the input to decode from331# @return [Time]332def decode_rtime(input)333input.value[0].value334end335336# Decodes the nonce field337#338# @param input [OpenSSL::ASN1::ASN1Data] the input to decode from339# @return [Integer]340def decode_nonce(input)341input.value[0].value.to_i342end343344# Decodes the etype field345#346# @param input [OpenSSL::ASN1::ASN1Data] the input to decode from347# @return [Array<Integer>]348def decode_etype(input)349encs = []350input.value[0].value.each do |enc|351encs << enc.value.to_i352end353encs354end355356# Decodes the hostaddresses field357#358# @param input [OpenSSL::ASN1::ASN1Data] the input to decode from359# @return [Array<Rex::Proto::Model::HostAddress>]360def decode_addresses(input)361caddr = []362input.value[0].value.each do |host_address_data|363caddr << Rex::Proto::Kerberos::Model::HostAddress.decode(host_address_data)364end365caddr366end367368# Decodes the enc_auth_data field369#370# @param input [OpenSSL::ASN1::ASN1Data] the input to decode from371# @return [Rex::Proto::Kerberos::Model::EncryptedData]372def decode_enc_auth_data(input)373Rex::Proto::Kerberos::Model::EncryptedData.decode(input.value[0])374end375376# Decodes the additional_tickets field377#378# @param input [OpenSSL::ASN1::ASN1Data] the input to decode from379# @return [Array<Rex::Proto::Kerberos::Model::EncryptedData>]380def decode_additional_tickets(input)381encs = []382input.value[0].value.each do |enc_ticket|383encs << enc_ticket.decode384end385encs386end387388end389end390end391end392end393394395