95 lines
3.4 KiB
Ruby
95 lines
3.4 KiB
Ruby
# -*- ruby encoding: utf-8 -*-
|
|
##
|
|
# BER extensions to the Array class.
|
|
module Net::BER::Extensions::Array
|
|
##
|
|
# Converts an Array to a BER sequence. All values in the Array are
|
|
# expected to be in BER format prior to calling this method.
|
|
def to_ber(id = 0)
|
|
# The universal sequence tag 0x30 is composed of the base tag value
|
|
# (0x10) and the constructed flag (0x20).
|
|
to_ber_seq_internal(0x30 + id)
|
|
end
|
|
alias_method :to_ber_sequence, :to_ber
|
|
|
|
##
|
|
# Converts an Array to a BER set. All values in the Array are expected to
|
|
# be in BER format prior to calling this method.
|
|
def to_ber_set(id = 0)
|
|
# The universal set tag 0x31 is composed of the base tag value (0x11)
|
|
# and the constructed flag (0x20).
|
|
to_ber_seq_internal(0x31 + id)
|
|
end
|
|
|
|
##
|
|
# Converts an Array to an application-specific sequence, assigned a tag
|
|
# value that is meaningful to the particular protocol being used. All
|
|
# values in the Array are expected to be in BER format pr prior to calling
|
|
# this method.
|
|
#--
|
|
# Implementor's note 20100320(AZ): RFC 4511 (the LDAPv3 protocol) as well
|
|
# as earlier RFCs 1777 and 2559 seem to indicate that LDAP only has
|
|
# application constructed sequences (0x60). However, ldapsearch sends some
|
|
# context-specific constructed sequences (0xA0); other clients may do the
|
|
# same. This behaviour appears to violate the RFCs. In real-world
|
|
# practice, we may need to change calls of #to_ber_appsequence to
|
|
# #to_ber_contextspecific for full LDAP server compatibility.
|
|
#
|
|
# This note probably belongs elsewhere.
|
|
#++
|
|
def to_ber_appsequence(id = 0)
|
|
# The application sequence tag always starts from the application flag
|
|
# (0x40) and the constructed flag (0x20).
|
|
to_ber_seq_internal(0x60 + id)
|
|
end
|
|
|
|
##
|
|
# Converts an Array to a context-specific sequence, assigned a tag value
|
|
# that is meaningful to the particular context of the particular protocol
|
|
# being used. All values in the Array are expected to be in BER format
|
|
# prior to calling this method.
|
|
def to_ber_contextspecific(id = 0)
|
|
# The application sequence tag always starts from the context flag
|
|
# (0x80) and the constructed flag (0x20).
|
|
to_ber_seq_internal(0xa0 + id)
|
|
end
|
|
|
|
##
|
|
# The internal sequence packing routine. All values in the Array are
|
|
# expected to be in BER format prior to calling this method.
|
|
def to_ber_seq_internal(code)
|
|
s = self.join
|
|
[code].pack('C') + s.length.to_ber_length_encoding + s
|
|
end
|
|
private :to_ber_seq_internal
|
|
|
|
##
|
|
# SNMP Object Identifiers (OID) are special arrays
|
|
#--
|
|
# 20100320 AZ: I do not think that this method should be in BER, since
|
|
# this appears to be SNMP-specific. This should probably be subsumed by a
|
|
# proper SNMP OID object.
|
|
#++
|
|
def to_ber_oid
|
|
ary = self.dup
|
|
first = ary.shift
|
|
raise Net::BER::BerError, "Invalid OID" unless [0, 1, 2].include?(first)
|
|
first = first * 40 + ary.shift
|
|
ary.unshift first
|
|
oid = ary.pack("w*")
|
|
[6, oid.length].pack("CC") + oid
|
|
end
|
|
|
|
##
|
|
# Converts an array into a set of ber control codes
|
|
# The expected format is [[control_oid, criticality, control_value(optional)]]
|
|
# [['1.2.840.113556.1.4.805',true]]
|
|
#
|
|
def to_ber_control
|
|
ary = self.collect do |control_sequence|
|
|
control_sequence.collect{|element| element.to_ber}.to_ber_sequence
|
|
end
|
|
ary.to_ber_sequence #putting this on a new line to make it more readable.
|
|
end
|
|
end
|