Skip to content

Commit 473a777

Browse files
author
blackhedd
committed
Moved the netxxx scripts down to net/xxx.
1 parent 7b049aa commit 473a777

File tree

4 files changed

+621
-2
lines changed

4 files changed

+621
-2
lines changed

lib/net/ber.rb

Lines changed: 282 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,282 @@
1+
# $Id$
2+
#
3+
# NET::BER
4+
# Mixes ASN.1/BER convenience methods into several standard classes.
5+
# Also provides BER parsing functionality.
6+
#
7+
#----------------------------------------------------------------------------
8+
#
9+
# Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved.
10+
#
11+
# Gmail: garbagecat10
12+
#
13+
# This program is free software; you can redistribute it and/or modify
14+
# it under the terms of the GNU General Public License as published by
15+
# the Free Software Foundation; either version 2 of the License, or
16+
# (at your option) any later version.
17+
#
18+
# This program is distributed in the hope that it will be useful,
19+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
20+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21+
# GNU General Public License for more details.
22+
#
23+
# You should have received a copy of the GNU General Public License
24+
# along with this program; if not, write to the Free Software
25+
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26+
#
27+
#---------------------------------------------------------------------------
28+
#
29+
#
30+
31+
32+
33+
34+
module Net
35+
36+
module BER
37+
38+
class BerError < Exception; end
39+
40+
41+
# This module is for mixing into IO and IO-like objects.
42+
module BERParser
43+
44+
# The order of these follows the class-codes in BER.
45+
# Maybe this should have been a hash.
46+
TagClasses = [:universal, :application, :context_specific, :private]
47+
48+
BuiltinSyntax = {
49+
:universal => {
50+
:primitive => {
51+
1 => :boolean,
52+
2 => :integer,
53+
4 => :string,
54+
10 => :integer,
55+
},
56+
:constructed => {
57+
16 => :array,
58+
17 => :array
59+
}
60+
}
61+
}
62+
63+
#
64+
# read_ber
65+
# TODO: clean this up so it works properly with partial
66+
# packets coming from streams that don't block when
67+
# we ask for more data (like StringIOs). At it is,
68+
# this can throw TypeErrors and other nasties.
69+
#
70+
def read_ber syntax=nil
71+
eof? and return nil
72+
73+
id = getc # don't trash this value, we'll use it later
74+
tag = id & 31
75+
tag < 31 or raise BerError.new( "unsupported tag encoding: #{id}" )
76+
tagclass = TagClasses[ id >> 6 ]
77+
encoding = (id & 0x20 != 0) ? :constructed : :primitive
78+
79+
n = getc
80+
lengthlength,contentlength = if n <= 127
81+
[1,n]
82+
else
83+
j = (0...(n & 127)).inject(0) {|mem,x| mem = (mem << 8) + getc}
84+
[1 + (n & 127), j]
85+
end
86+
87+
newobj = read contentlength
88+
89+
objtype = nil
90+
[syntax, BuiltinSyntax].each {|syn|
91+
if syn && (ot = syn[tagclass]) && (ot = ot[encoding]) && ot[tag]
92+
objtype = ot[tag]
93+
break
94+
end
95+
}
96+
97+
obj = case objtype
98+
when :boolean
99+
newobj != "\000"
100+
when :string
101+
(newobj || "").dup
102+
when :integer
103+
j = 0
104+
newobj.each_byte {|b| j = (j << 8) + b}
105+
j
106+
when :array
107+
seq = []
108+
sio = StringIO.new( newobj || "" )
109+
while e = sio.read_ber(syntax); seq << e; end
110+
seq
111+
else
112+
raise BerError.new( "unsupported object type: class=#{tagclass}, encoding=#{encoding}, tag=#{tag}" )
113+
end
114+
115+
# Add the identifier bits into the object if it's a String or an Array.
116+
# We can't add extra stuff to Fixnums and booleans, not that it makes much sense anyway.
117+
obj and ([String,Array].include? obj.class) and obj.instance_eval "def ber_identifier; #{id}; end"
118+
obj
119+
120+
end
121+
122+
end # module BERParser
123+
end # module BER
124+
125+
end # module Net
126+
127+
128+
class IO
129+
include Net::BER::BERParser
130+
end
131+
132+
require "stringio"
133+
class StringIO
134+
include Net::BER::BERParser
135+
end
136+
137+
138+
class String
139+
def read_ber syntax=nil
140+
StringIO.new(self).read_ber(syntax)
141+
end
142+
end
143+
144+
145+
146+
#----------------------------------------------
147+
148+
149+
class FalseClass
150+
#
151+
# to_ber
152+
#
153+
def to_ber
154+
"\001\001\000"
155+
end
156+
end
157+
158+
159+
class TrueClass
160+
#
161+
# to_ber
162+
#
163+
def to_ber
164+
"\001\001\001"
165+
end
166+
end
167+
168+
169+
170+
class Fixnum
171+
#
172+
# to_ber
173+
#
174+
def to_ber
175+
i = [self].pack('w')
176+
[2, i.length].pack("CC") + i
177+
end
178+
179+
#
180+
# to_ber_enumerated
181+
#
182+
def to_ber_enumerated
183+
i = [self].pack('w')
184+
[10, i.length].pack("CC") + i
185+
end
186+
187+
#
188+
# to_ber_length_encoding
189+
#
190+
def to_ber_length_encoding
191+
if self <= 127
192+
[self].pack('C')
193+
else
194+
i = [self].pack('N').sub(/^[\0]+/,"")
195+
[0x80 + i.length].pack('C') + i
196+
end
197+
end
198+
199+
end # class Fixnum
200+
201+
202+
class Bignum
203+
204+
def to_ber
205+
i = [self].pack('w')
206+
i.length > 126 and raise Net::BER::BerError.new( "range error in bignum" )
207+
[2, i.length].pack("CC") + i
208+
end
209+
210+
end
211+
212+
213+
214+
class String
215+
#
216+
# to_ber
217+
# A universal octet-string is tag number 4,
218+
# but others are possible depending on the context, so we
219+
# let the caller give us one.
220+
#
221+
def to_ber code = 4
222+
[code].pack('C') + length.to_ber_length_encoding + self
223+
end
224+
225+
#
226+
# to_ber_application_string
227+
# TODO. WARNING, IS THIS WRONG? Shouldn't app-specific string
228+
# have a prefix of 0x40?
229+
#
230+
def to_ber_application_string code
231+
to_ber( 0x80 + code )
232+
end
233+
234+
#
235+
# to_ber_contextspecific
236+
#
237+
def to_ber_contextspecific code
238+
to_ber( 0x80 + code )
239+
end
240+
241+
end # class String
242+
243+
244+
245+
class Array
246+
#
247+
# to_ber_appsequence
248+
# An application-specific sequence usually gets assigned
249+
# a tag that is meaningful to the particular protocol being used.
250+
# This is different from the universal sequence, which usually
251+
# gets a tag value of 16.
252+
# Now here's an interesting thing: We're adding the X.690
253+
# "application constructed" code at the top of the tag byte (0x60),
254+
# but some clients, notably ldapsearch, send "context-specific
255+
# constructed" (0xA0). The latter would appear to violate RFC-1777,
256+
# but what do I know? We may need to change this.
257+
#
258+
259+
def to_ber id = 0; to_ber_seq_internal( 0x30 + id ); end
260+
def to_ber_set id = 0; to_ber_seq_internal( 0x31 + id ); end
261+
def to_ber_sequence id = 0; to_ber_seq_internal( 0x30 + id ); end
262+
def to_ber_appsequence id = 0; to_ber_seq_internal( 0x60 + id ); end
263+
def to_ber_contextspecific id = 0; to_ber_seq_internal( 0xA0 + id ); end
264+
265+
private
266+
def to_ber_seq_internal code
267+
s = self.to_s
268+
[code].pack('C') + s.length.to_ber_length_encoding + s
269+
end
270+
271+
end # class Array
272+
273+
274+
275+
#----------------------------------------------
276+
277+
if __FILE__ == $0
278+
puts "No default action"
279+
end
280+
281+
282+

lib/net/ldap.rb

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,6 @@
3939
#
4040

4141

42-
#require 'rubygems'
43-
#require_gem "eventmachine", ">= 0.3.1"
4442

4543
require 'socket'
4644

0 commit comments

Comments
 (0)