diff .svn/pristine/60/60a7eaf3b71f4ea5a952f91807abdd540583522f.svn-base @ 909:cbb26bc654de redmine-1.3

Update to Redmine 1.3-stable branch (Redmine SVN rev 8964)
author Chris Cannam
date Fri, 24 Feb 2012 19:09:32 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.svn/pristine/60/60a7eaf3b71f4ea5a952f91807abdd540583522f.svn-base	Fri Feb 24 19:09:32 2012 +0000
@@ -0,0 +1,205 @@
+# $Id: pdu.rb 126 2006-05-31 15:55:16Z blackhedd $
+#
+# LDAP PDU support classes
+#
+#
+#----------------------------------------------------------------------------
+#
+# Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved.
+#
+# Gmail: garbagecat10
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+#
+#---------------------------------------------------------------------------
+#
+
+
+
+module Net
+
+
+class LdapPduError < Exception; end
+
+
+class LdapPdu
+
+  BindResult = 1
+  SearchReturnedData = 4
+  SearchResult = 5
+  ModifyResponse = 7
+  AddResponse = 9
+  DeleteResponse = 11
+  ModifyRDNResponse = 13
+  SearchResultReferral = 19
+
+  attr_reader :msg_id, :app_tag
+  attr_reader :search_dn, :search_attributes, :search_entry
+  attr_reader :search_referrals
+
+  #
+  # initialize
+  # An LDAP PDU always looks like a BerSequence with
+  # at least two elements: an integer (message-id number), and
+  # an application-specific sequence.
+  # Some LDAPv3 packets also include an optional
+  # third element, which is a sequence of "controls"
+  # (See RFC 2251, section 4.1.12).
+  # The application-specific tag in the sequence tells
+  # us what kind of packet it is, and each kind has its
+  # own format, defined in RFC-1777.
+  # Observe that many clients (such as ldapsearch)
+  # do not necessarily enforce the expected application
+  # tags on received protocol packets. This implementation
+  # does interpret the RFC strictly in this regard, and
+  # it remains to be seen whether there are servers out
+  # there that will not work well with our approach.
+  #
+  # Added a controls-processor to SearchResult.
+  # Didn't add it everywhere because it just _feels_
+  # like it will need to be refactored.
+  #
+  def initialize ber_object
+    begin
+      @msg_id = ber_object[0].to_i
+      @app_tag = ber_object[1].ber_identifier - 0x60
+    rescue
+      # any error becomes a data-format error
+      raise LdapPduError.new( "ldap-pdu format error" )
+    end
+
+    case @app_tag
+    when BindResult
+      parse_ldap_result ber_object[1]
+    when SearchReturnedData
+      parse_search_return ber_object[1]
+    when SearchResultReferral
+      parse_search_referral ber_object[1]
+    when SearchResult
+      parse_ldap_result ber_object[1]
+      parse_controls(ber_object[2]) if ber_object[2]
+    when ModifyResponse
+      parse_ldap_result ber_object[1]
+    when AddResponse
+      parse_ldap_result ber_object[1]
+    when DeleteResponse
+      parse_ldap_result ber_object[1]
+    when ModifyRDNResponse
+      parse_ldap_result ber_object[1]
+    else
+      raise LdapPduError.new( "unknown pdu-type: #{@app_tag}" )
+    end
+  end
+
+  #
+  # result_code
+  # This returns an LDAP result code taken from the PDU,
+  # but it will be nil if there wasn't a result code.
+  # That can easily happen depending on the type of packet.
+  #
+  def result_code code = :resultCode
+    @ldap_result and @ldap_result[code]
+  end
+
+  # Return RFC-2251 Controls if any.
+  # Messy. Does this functionality belong somewhere else?
+  def result_controls
+    @ldap_controls || []
+  end
+
+
+  #
+  # parse_ldap_result
+  #
+  def parse_ldap_result sequence
+    sequence.length >= 3 or raise LdapPduError
+    @ldap_result = {:resultCode => sequence[0], :matchedDN => sequence[1], :errorMessage => sequence[2]}
+  end
+  private :parse_ldap_result
+
+  #
+  # parse_search_return
+  # Definition from RFC 1777 (we're handling application-4 here)
+  #
+  # Search Response ::=
+  #    CHOICE {
+  #         entry          [APPLICATION 4] SEQUENCE {
+  #                             objectName     LDAPDN,
+  #                             attributes     SEQUENCE OF SEQUENCE {
+  #                                                 AttributeType,
+  #                                                 SET OF AttributeValue
+  #                                            }
+  #                        },
+  #         resultCode     [APPLICATION 5] LDAPResult
+  #     }
+  #
+  # We concoct a search response that is a hash of the returned attribute values.
+  # NOW OBSERVE CAREFULLY: WE ARE DOWNCASING THE RETURNED ATTRIBUTE NAMES.
+  # This is to make them more predictable for user programs, but it
+  # may not be a good idea. Maybe this should be configurable.
+  # ALTERNATE IMPLEMENTATION: In addition to @search_dn and @search_attributes,
+  # we also return @search_entry, which is an LDAP::Entry object.
+  # If that works out well, then we'll remove the first two.
+  #
+  # Provisionally removed obsolete search_attributes and search_dn, 04May06.
+  #
+  def parse_search_return sequence
+    sequence.length >= 2 or raise LdapPduError
+    @search_entry = LDAP::Entry.new( sequence[0] )
+    #@search_dn = sequence[0]
+    #@search_attributes = {}
+    sequence[1].each {|seq|
+      @search_entry[seq[0]] = seq[1]
+      #@search_attributes[seq[0].downcase.intern] = seq[1]
+    }
+  end
+
+  #
+  # A search referral is a sequence of one or more LDAP URIs.
+  # Any number of search-referral replies can be returned by the server, interspersed
+  # with normal replies in any order.
+  # Until I can think of a better way to do this, we'll return the referrals as an array.
+  # It'll be up to higher-level handlers to expose something reasonable to the client.
+  def parse_search_referral uris
+    @search_referrals = uris
+  end
+
+
+  # Per RFC 2251, an LDAP "control" is a sequence of tuples, each consisting
+  # of an OID, a boolean criticality flag defaulting FALSE, and an OPTIONAL
+  # Octet String. If only two fields are given, the second one may be
+  # either criticality or data, since criticality has a default value.
+  # Someday we may want to come back here and add support for some of
+  # more-widely used controls. RFC-2696 is a good example.
+  #
+  def parse_controls sequence
+    @ldap_controls = sequence.map do |control|
+      o = OpenStruct.new
+      o.oid,o.criticality,o.value = control[0],control[1],control[2]
+      if o.criticality and o.criticality.is_a?(String)
+        o.value = o.criticality
+        o.criticality = false
+      end
+      o
+    end
+  end
+  private :parse_controls
+
+
+end
+
+
+end # module Net
+