Mercurial > hg > soundsoftware-site
comparison .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 |
comparison
equal
deleted
inserted
replaced
908:c6c2cbd0afee | 909:cbb26bc654de |
---|---|
1 # $Id: pdu.rb 126 2006-05-31 15:55:16Z blackhedd $ | |
2 # | |
3 # LDAP PDU support classes | |
4 # | |
5 # | |
6 #---------------------------------------------------------------------------- | |
7 # | |
8 # Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved. | |
9 # | |
10 # Gmail: garbagecat10 | |
11 # | |
12 # This program is free software; you can redistribute it and/or modify | |
13 # it under the terms of the GNU General Public License as published by | |
14 # the Free Software Foundation; either version 2 of the License, or | |
15 # (at your option) any later version. | |
16 # | |
17 # This program is distributed in the hope that it will be useful, | |
18 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
19 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20 # GNU General Public License for more details. | |
21 # | |
22 # You should have received a copy of the GNU General Public License | |
23 # along with this program; if not, write to the Free Software | |
24 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
25 # | |
26 #--------------------------------------------------------------------------- | |
27 # | |
28 | |
29 | |
30 | |
31 module Net | |
32 | |
33 | |
34 class LdapPduError < Exception; end | |
35 | |
36 | |
37 class LdapPdu | |
38 | |
39 BindResult = 1 | |
40 SearchReturnedData = 4 | |
41 SearchResult = 5 | |
42 ModifyResponse = 7 | |
43 AddResponse = 9 | |
44 DeleteResponse = 11 | |
45 ModifyRDNResponse = 13 | |
46 SearchResultReferral = 19 | |
47 | |
48 attr_reader :msg_id, :app_tag | |
49 attr_reader :search_dn, :search_attributes, :search_entry | |
50 attr_reader :search_referrals | |
51 | |
52 # | |
53 # initialize | |
54 # An LDAP PDU always looks like a BerSequence with | |
55 # at least two elements: an integer (message-id number), and | |
56 # an application-specific sequence. | |
57 # Some LDAPv3 packets also include an optional | |
58 # third element, which is a sequence of "controls" | |
59 # (See RFC 2251, section 4.1.12). | |
60 # The application-specific tag in the sequence tells | |
61 # us what kind of packet it is, and each kind has its | |
62 # own format, defined in RFC-1777. | |
63 # Observe that many clients (such as ldapsearch) | |
64 # do not necessarily enforce the expected application | |
65 # tags on received protocol packets. This implementation | |
66 # does interpret the RFC strictly in this regard, and | |
67 # it remains to be seen whether there are servers out | |
68 # there that will not work well with our approach. | |
69 # | |
70 # Added a controls-processor to SearchResult. | |
71 # Didn't add it everywhere because it just _feels_ | |
72 # like it will need to be refactored. | |
73 # | |
74 def initialize ber_object | |
75 begin | |
76 @msg_id = ber_object[0].to_i | |
77 @app_tag = ber_object[1].ber_identifier - 0x60 | |
78 rescue | |
79 # any error becomes a data-format error | |
80 raise LdapPduError.new( "ldap-pdu format error" ) | |
81 end | |
82 | |
83 case @app_tag | |
84 when BindResult | |
85 parse_ldap_result ber_object[1] | |
86 when SearchReturnedData | |
87 parse_search_return ber_object[1] | |
88 when SearchResultReferral | |
89 parse_search_referral ber_object[1] | |
90 when SearchResult | |
91 parse_ldap_result ber_object[1] | |
92 parse_controls(ber_object[2]) if ber_object[2] | |
93 when ModifyResponse | |
94 parse_ldap_result ber_object[1] | |
95 when AddResponse | |
96 parse_ldap_result ber_object[1] | |
97 when DeleteResponse | |
98 parse_ldap_result ber_object[1] | |
99 when ModifyRDNResponse | |
100 parse_ldap_result ber_object[1] | |
101 else | |
102 raise LdapPduError.new( "unknown pdu-type: #{@app_tag}" ) | |
103 end | |
104 end | |
105 | |
106 # | |
107 # result_code | |
108 # This returns an LDAP result code taken from the PDU, | |
109 # but it will be nil if there wasn't a result code. | |
110 # That can easily happen depending on the type of packet. | |
111 # | |
112 def result_code code = :resultCode | |
113 @ldap_result and @ldap_result[code] | |
114 end | |
115 | |
116 # Return RFC-2251 Controls if any. | |
117 # Messy. Does this functionality belong somewhere else? | |
118 def result_controls | |
119 @ldap_controls || [] | |
120 end | |
121 | |
122 | |
123 # | |
124 # parse_ldap_result | |
125 # | |
126 def parse_ldap_result sequence | |
127 sequence.length >= 3 or raise LdapPduError | |
128 @ldap_result = {:resultCode => sequence[0], :matchedDN => sequence[1], :errorMessage => sequence[2]} | |
129 end | |
130 private :parse_ldap_result | |
131 | |
132 # | |
133 # parse_search_return | |
134 # Definition from RFC 1777 (we're handling application-4 here) | |
135 # | |
136 # Search Response ::= | |
137 # CHOICE { | |
138 # entry [APPLICATION 4] SEQUENCE { | |
139 # objectName LDAPDN, | |
140 # attributes SEQUENCE OF SEQUENCE { | |
141 # AttributeType, | |
142 # SET OF AttributeValue | |
143 # } | |
144 # }, | |
145 # resultCode [APPLICATION 5] LDAPResult | |
146 # } | |
147 # | |
148 # We concoct a search response that is a hash of the returned attribute values. | |
149 # NOW OBSERVE CAREFULLY: WE ARE DOWNCASING THE RETURNED ATTRIBUTE NAMES. | |
150 # This is to make them more predictable for user programs, but it | |
151 # may not be a good idea. Maybe this should be configurable. | |
152 # ALTERNATE IMPLEMENTATION: In addition to @search_dn and @search_attributes, | |
153 # we also return @search_entry, which is an LDAP::Entry object. | |
154 # If that works out well, then we'll remove the first two. | |
155 # | |
156 # Provisionally removed obsolete search_attributes and search_dn, 04May06. | |
157 # | |
158 def parse_search_return sequence | |
159 sequence.length >= 2 or raise LdapPduError | |
160 @search_entry = LDAP::Entry.new( sequence[0] ) | |
161 #@search_dn = sequence[0] | |
162 #@search_attributes = {} | |
163 sequence[1].each {|seq| | |
164 @search_entry[seq[0]] = seq[1] | |
165 #@search_attributes[seq[0].downcase.intern] = seq[1] | |
166 } | |
167 end | |
168 | |
169 # | |
170 # A search referral is a sequence of one or more LDAP URIs. | |
171 # Any number of search-referral replies can be returned by the server, interspersed | |
172 # with normal replies in any order. | |
173 # Until I can think of a better way to do this, we'll return the referrals as an array. | |
174 # It'll be up to higher-level handlers to expose something reasonable to the client. | |
175 def parse_search_referral uris | |
176 @search_referrals = uris | |
177 end | |
178 | |
179 | |
180 # Per RFC 2251, an LDAP "control" is a sequence of tuples, each consisting | |
181 # of an OID, a boolean criticality flag defaulting FALSE, and an OPTIONAL | |
182 # Octet String. If only two fields are given, the second one may be | |
183 # either criticality or data, since criticality has a default value. | |
184 # Someday we may want to come back here and add support for some of | |
185 # more-widely used controls. RFC-2696 is a good example. | |
186 # | |
187 def parse_controls sequence | |
188 @ldap_controls = sequence.map do |control| | |
189 o = OpenStruct.new | |
190 o.oid,o.criticality,o.value = control[0],control[1],control[2] | |
191 if o.criticality and o.criticality.is_a?(String) | |
192 o.value = o.criticality | |
193 o.criticality = false | |
194 end | |
195 o | |
196 end | |
197 end | |
198 private :parse_controls | |
199 | |
200 | |
201 end | |
202 | |
203 | |
204 end # module Net | |
205 |