cul-handles 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.2.0
@@ -0,0 +1,79 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{cul-handles}
8
+ s.version = "0.2.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["James Stuart"]
12
+ s.date = %q{2009-11-11}
13
+ s.description = %q{Columbia client to deal with handle server}
14
+ s.email = %q{tastyhat@jamesstuart.org}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "LICENSE",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "cul-handles.gemspec",
27
+ "lib/cul-handles.rb",
28
+ "lib/cul/handles/base_message.rb",
29
+ "lib/cul/handles/base_request.rb",
30
+ "lib/cul/handles/base_response.rb",
31
+ "lib/cul/handles/challenge_answer_request.rb",
32
+ "lib/cul/handles/challenge_response.rb",
33
+ "lib/cul/handles/client.rb",
34
+ "lib/cul/handles/create_handle_request.rb",
35
+ "lib/cul/handles/delete_handle_request.rb",
36
+ "lib/cul/handles/delete_value_request.rb",
37
+ "lib/cul/handles/handle_value_request.rb",
38
+ "lib/cul/handles/hdl.rb",
39
+ "lib/cul/handles/modify_value_request.rb",
40
+ "lib/cul/handles/resolution_request.rb",
41
+ "lib/cul/handles/resolution_response.rb",
42
+ "lib/cul/handles/session_request.rb",
43
+ "lib/cul/handles/session_setup_response.rb",
44
+ "lib/cul/handles/set_value_request.rb",
45
+ "test/authn_test.rb",
46
+ "test/cul-handles_test.rb",
47
+ "test/dh_test.rb",
48
+ "test/resolution_test.rb",
49
+ "test/test_helper.rb",
50
+ "test/unsigned_integer_test.rb"
51
+ ]
52
+ s.homepage = %q{http://github.com/tastyhat/cul-handles}
53
+ s.rdoc_options = ["--charset=UTF-8"]
54
+ s.require_paths = ["lib"]
55
+ s.rubygems_version = %q{1.3.5}
56
+ s.summary = %q{CUL Handle Client}
57
+ s.test_files = [
58
+ "test/authn_test.rb",
59
+ "test/cul-handles_test.rb",
60
+ "test/dh_test.rb",
61
+ "test/resolution_test.rb",
62
+ "test/test_helper.rb",
63
+ "test/unsigned_integer_test.rb"
64
+ ]
65
+
66
+ if s.respond_to? :specification_version then
67
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
68
+ s.specification_version = 3
69
+
70
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
71
+ s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
72
+ else
73
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
74
+ end
75
+ else
76
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
77
+ end
78
+ end
79
+
@@ -0,0 +1,121 @@
1
+ module Cul
2
+ module Handles
3
+ class BaseMessage
4
+ include Hdl
5
+ def initialize
6
+ @SHA1 = Digest::SHA1.new()
7
+ @MD5 = Digest::MD5.new()
8
+ @digest = [nil,@MD5,@SHA1]
9
+ @majorVersion = 2 # default
10
+ @minorVersion = 1 # default
11
+ @digestAlg = 2 # SHA1 = 2, MD5 = 1
12
+ @digestLength = 20 # SHA1 = 20 octets, MD5 = 16
13
+ @sequenceNumber = [0,0,0,0]
14
+
15
+ end
16
+
17
+ def authoritative=(val)
18
+ if(val)
19
+ @opFlag[MSG_FLAG_AUTH_INDEX] |= MSG_FLAG_AUTH
20
+ else
21
+ @opFlag[MSG_FLAG_AUTH_INDEX] &= ~MSG_FLAG_AUTH
22
+ end
23
+ end
24
+ def authoritative()
25
+ return @opFlag[MSG_FLAG_AUTH_INDEX] & MSG_FLAG_AUTH > 0
26
+ end
27
+ def certify=(val)
28
+ if(val)
29
+ @opFlag[MSG_FLAG_CERT_INDEX] |= MSG_FLAG_CERT
30
+ else
31
+ @opFlag[MSG_FLAG_CERT_INDEX] &= ~MSG_FLAG_CERT
32
+ end
33
+ end
34
+ def certify()
35
+ return @opFlag[MSG_FLAG_CERT_INDEX] & MSG_FLAG_CERT > 0
36
+ end
37
+ def encrypt=(val)
38
+ if(val)
39
+ @opFlag[MSG_FLAG_ENCR_INDEX] |= MSG_FLAG_ENCR
40
+ else
41
+ @opFlag[MSG_FLAG_ENCR_INDEX] &= ~MSG_FLAG_ENCR
42
+ end
43
+ end
44
+ def encrypt()
45
+ return @opFlag[MSG_FLAG_ENCR_INDEX] & MSG_FLAG_ENCR > 0
46
+ end
47
+ def recursive=(val)
48
+ if(val)
49
+ @opFlag[MSG_FLAG_RECU_INDEX] |= MSG_FLAG_RECU
50
+ else
51
+ @opFlag[MSG_FLAG_RECU_INDEX] &= ~MSG_FLAG_RECU
52
+ end
53
+ end
54
+ def recursive()
55
+ return @opFlag[MSG_FLAG_RECU_INDEX] & MSG_FLAG_RECU > 0
56
+ end
57
+ def cacheCertify=(val)
58
+ if(val)
59
+ @opFlag[MSG_FLAG_CACR_INDEX] |= MSG_FLAG_CACR
60
+ else
61
+ @opFlag[MSG_FLAG_CACR_INDEX] &= ~MSG_FLAG_CACR
62
+ end
63
+ end
64
+ def cacheCertify()
65
+ return @opFlag[MSG_FLAG_CACR_INDEX] & MSG_FLAG_CACR > 0
66
+ end
67
+ def continuous=(val)
68
+ if(val)
69
+ @opFlag[MSG_FLAG_CONT_INDEX] |= MSG_FLAG_CONT
70
+ else
71
+ @opFlag[MSG_FLAG_CONT_INDEX] &= ~MSG_FLAG_CONT
72
+ end
73
+ end
74
+ def continuous()
75
+ return @opFlag[MSG_FLAG_CONT_INDEX] & MSG_FLAG_CONT > 0
76
+ end
77
+ def keepAlive=(val)
78
+ if(val)
79
+ @opFlag[MSG_FLAG_KPAL_INDEX] |= MSG_FLAG_KPAL
80
+ else
81
+ @opFlag[MSG_FLAG_KPAL_INDEX] &= ~MSG_FLAG_KPAL
82
+ end
83
+ end
84
+ def keepAlive()
85
+ return @opFlag[MSG_FLAG_KPAL_INDEX] & MSG_FLAG_KPAL > 0
86
+ end
87
+ def publicOnly=(val)
88
+ if(val)
89
+ @opFlag[MSG_FLAG_PUBL_INDEX] |= MSG_FLAG_PUBL
90
+ else
91
+ @opFlag[MSG_FLAG_PUBL_INDEX] &= ~MSG_FLAG_PUBL
92
+ end
93
+ end
94
+ def publicOnly()
95
+ return @opFlag[MSG_FLAG_PUBL_INDEX] & MSG_FLAG_PUBL > 0
96
+ end
97
+ def returnRequestDigest=(val)
98
+ if(val)
99
+ @opFlag[MSG_FLAG_RRDG_INDEX] |= MSG_FLAG_RRDG
100
+ else
101
+ @opFlag[MSG_FLAG_RRDG_INDEX] &= ~MSG_FLAG_RRDG
102
+ end
103
+ end
104
+ def returnRequestDigest()
105
+ return @opFlag[MSG_FLAG_RRDG_INDEX] & MSG_FLAG_RRDG > 0
106
+ end
107
+ def digestAlg=(val)
108
+ if(val == 1)
109
+ @digest = @MD5
110
+ @digestLength = 16
111
+ elsif(val == 2)
112
+ @digest = @SHA1
113
+ @digestLength = 20
114
+ else
115
+ @digest = nil
116
+ @digestLength = 0
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,153 @@
1
+ module Cul
2
+ module Handles
3
+ class BaseRequest < BaseMessage
4
+ def initialize()
5
+ super()
6
+ @body = []
7
+ @opFlag = [0,0,0,0]
8
+ @recursionCount = [0]
9
+ @messageFlag = [0,0]
10
+ @messageLength = [0,0,0,0]
11
+ @siteInfoSerial = [0xff,0xff]
12
+ @sessionId = [0,0,0,0]
13
+ @credential = [0,0,0,0]
14
+ end
15
+ def valid?()
16
+ return true
17
+ end
18
+ def opCode=(val)
19
+ @opCode=asBytes(val)
20
+ end
21
+ def opCode()
22
+ @opCode
23
+ end
24
+ def opFlag=(val)
25
+ @opFlag=asBytes(val)
26
+ end
27
+ def opFlag()
28
+ fromBytes(@opFlag)
29
+ end
30
+ def requestId=(val)
31
+ @requestId=asBytes(val)
32
+ end
33
+ def requestId()
34
+ fromBytes(@requestId)
35
+ end
36
+ def sessionId=(val)
37
+ @sessionId=asBytes(val)
38
+ end
39
+ def sessionId()
40
+ @sessionId
41
+ end
42
+ def siteInfoSerial=(val)
43
+ if val < 0
44
+ @siteInfoSerial=asBytes(65536 + val)[-2..-1]
45
+ else
46
+ @siteInfoSerial = asBytes(val)[-2..-1]
47
+ end
48
+ end
49
+ def siteInfoSerial()
50
+ return fromBytes(@siteInfoSerial)
51
+ end
52
+ def sequenceNumber()
53
+ fromBytes(@sequenceNumber)
54
+ end
55
+ def sequenceNumber=(val)
56
+ @sequenceNumber=asBytes(val)
57
+ end
58
+ def recursionCount()
59
+ fromBytes(@recursionCount)
60
+ end
61
+ def recursionCount=(val)
62
+ @recursionCount=asBytes(val)
63
+ end
64
+ def expirationTime()
65
+ fromBytes(@expirationTime)
66
+ end
67
+ def expirationTime=(val)
68
+ @expirationTime=asBytes(val)
69
+ end
70
+ def responseCode=(val)
71
+ @responseCode=asBytes(val)
72
+ end
73
+ def responseCode
74
+ @responseCode
75
+ end
76
+ def credentialVersion()
77
+ return []
78
+ end
79
+ def credentialReserved()
80
+ return []
81
+ end
82
+ def credentialOptions()
83
+ return []
84
+ end
85
+ def credentialSigner()
86
+ return []
87
+ end
88
+ def credentialType()
89
+ return []
90
+ end
91
+ def credentialDigestAlg()
92
+ return []
93
+ end
94
+ def encodeCredential()
95
+ creds = [].concat(self.credentialVersion).concat(self.credentialReserved).concat(self.credentialOptions()).concat(self.credentialSigner).concat(self.credentialType)
96
+ creds = asBytes(creds.length).concat(creds)
97
+ @credential = creds
98
+ end
99
+ def credential()
100
+ @credential
101
+ end
102
+ def messageFlag=(val)
103
+ @messageFlag = val
104
+ end
105
+ def envelope
106
+ e = [@majorVersion, @minorVersion]
107
+ e.concat(@messageFlag)
108
+ e.concat(@sessionId)
109
+ e.concat(@requestId)
110
+ e.concat(@sequenceNumber)
111
+ e.concat(asBytes(@body.length + 24 + @credential.length))
112
+ e
113
+ end
114
+ def messageFlag
115
+ return @messageFlag
116
+ end
117
+ def messageLength
118
+ @body.length + 24 + @credential.length
119
+ end
120
+ def header
121
+ result = [].concat(self.opCode)
122
+ result.concat(@responseCode)
123
+ result.concat(@opFlag)
124
+ result.concat(@siteInfoSerial)
125
+ result.concat(@recursionCount)
126
+ result.concat([0])
127
+ result.concat(@expirationTime)
128
+ result.concat(asBytes(@body.length))
129
+ return result
130
+ end
131
+ def body
132
+ return @body
133
+ end
134
+ def encodeBody()
135
+ return
136
+ end
137
+ def bodyLength
138
+ return asBytes(@body.length)
139
+ end
140
+ def digest(data)
141
+ return @SHA1.digest(data.pack('U*')).unpack('c*')
142
+ end
143
+ def packet
144
+ encodeBody()
145
+ encodeCredential()
146
+ result = envelope().concat(header())
147
+ result.concat(body())
148
+ result.concat(credential())
149
+ return result
150
+ end
151
+ end
152
+ end
153
+ end
@@ -0,0 +1,191 @@
1
+ module Cul
2
+ module Handles
3
+
4
+ class BaseResponse < BaseMessage
5
+ include Hdl
6
+ def initialize
7
+ super()
8
+ @packet = []
9
+ @siteInfoSerial = [0,0]
10
+ @requestId = [0,0,0,0]
11
+ @sessionId = [0,0,0,0]
12
+ @opCode = [0,0,0,0]
13
+ @responseCode = [0,0,0,0]
14
+ @opFlag = [0,0,0,0]
15
+ @recursionCount = 0
16
+ @expirationTime = [0,0,0,0]
17
+ @bodyLength = 0
18
+ @debug = false
19
+ end
20
+ def debug=(val)
21
+ if(val)
22
+ @debug = true
23
+ else
24
+ @debug = false
25
+ end
26
+ end
27
+ def send(req,sock)
28
+ if not req.valid?()
29
+ raise "Request invalid: " + req.to_s
30
+ end
31
+ initialize()
32
+ bytes = req.packet
33
+ bctr = 0
34
+ puts "sending \n" + bytes.collect{|byte|
35
+ bctr = bctr + 1
36
+ if byte.nil?
37
+ "nil byte at " + bctr.to_s
38
+ else
39
+ "%02x" % byte
40
+ end
41
+ }.join if @debug
42
+ sent = sock.write(bytes.pack('C*'))
43
+
44
+ if sent != bytes.length
45
+ puts "Warning: Attempted to send " + bytes.length.to_s + "; actually sent " + sent.to_s
46
+ end
47
+ parseEnvelope(sock.recv(20).unpack('C*'))
48
+ puts "parsed envelope" if @debug
49
+ parseHeader(sock.recv(24).unpack('C*'))
50
+ puts "parsed header" if @debug
51
+ parseBody(sock.recv(@bodyLength).unpack('C*'))
52
+ puts "parsed body" if @debug
53
+ parseCredential(Array.new())
54
+ end
55
+ def parseEnvelope(data)
56
+ "parseEnvelope"
57
+ if(data.length != 20)
58
+ puts("Unexpected envelope length: " + data.length.to_s)
59
+ return
60
+ end
61
+ @packet.concat(data)
62
+ # version info
63
+ @majorVersion = data[0]
64
+ @minorVersion = data[1]
65
+ # message flag
66
+ mflag = data[2] # actually 2 octets, but second octet is reserved
67
+ if ((mflag & Hdl::ENV_FLAG_COMPRESSED) == Hdl::ENV_FLAG_COMPRESSED)
68
+ @compressed = true
69
+ end
70
+ if ((mflag & Hdl::ENV_FLAG_ENCRYPTED) == Hdl::ENV_FLAG_ENCRYPTED)
71
+ @encrypted = true
72
+ end
73
+ if ((mflag & Hdl::ENV_FLAG_TRUNCATED) == Hdl::ENV_FLAG_TRUNCATED)
74
+ @truncated = true
75
+ end
76
+ # session id
77
+ @sessionId = data[4..7]
78
+ # request id
79
+ @requestId = data[8..11]
80
+ # sequence number
81
+ @sequenceNumber = data[12..15]
82
+ # message length
83
+ @messageLength = data[16..19]
84
+ end
85
+ def sessionId
86
+ return fromBytes(@sessionId)
87
+ end
88
+ def requestId
89
+ return fromBytes(@requestId)
90
+ end
91
+ def parseHeader(data)
92
+ @packet.concat(data)
93
+ if(data.length != 24)
94
+ puts("Unexpected header length: " + data.length.to_s)
95
+ return
96
+ end
97
+ @opCode = data[0..3]
98
+ @responseCode = data[4..7]
99
+ @opFlag = data[8..11]
100
+ @siteInfoSerial = data[12..13]
101
+ @recursionCount = data[14]
102
+ @expirationTime = data[16..19]
103
+ @bodyLength = fromBytes(data[20..23])
104
+ if(@bodyLength < 1)
105
+ puts "Unexpected @bodyLength: " + @bodyLength.to_s
106
+ end
107
+ end
108
+ def opCode
109
+ return fromBytes(@opCode)
110
+ end
111
+ def responseCode
112
+ return fromBytes(@responseCode)
113
+ end
114
+ def success?
115
+ return @responseCode.eql?([0,0,0,1])
116
+ end
117
+ def siteInfoSerial
118
+ return fromBytes(@siteInfoSerial)
119
+ end
120
+ def parseBody(data)
121
+ offset = 0
122
+ @packet.concat(data)
123
+ # parse return digest
124
+ if self.returnRequestDigest()
125
+ self.digestAlg = data[offset]
126
+ if (@digestLength)
127
+ @messageDigest = data[1..(@digestLength)]
128
+ offset = 1 + @digestLength
129
+ else
130
+ @messageDigest = []
131
+ end
132
+ end
133
+ @body = data[offset...@bodyLength]
134
+ end
135
+ def body
136
+ @body
137
+ end
138
+ def parseCredential(data)
139
+ offset = 0
140
+ @packet.concat(data)
141
+ # parse credential
142
+ if (data.length > 0)
143
+ @credentialVersion = data[offset]
144
+ offset = offset + 2
145
+ @credentialOptions = data[offset..offset+1]
146
+ offset = offset + 2
147
+ @credential = data[offset...(offset+credentialLength)]
148
+ offset = offset + credentialLength
149
+ pstringData = readProtocolString(data,offset)
150
+ offset = offset + pstringData[0]
151
+ type = pstringData[1]
152
+ signedInfoLength = fromBytes(data[offset...offset+4])
153
+ offset = offset + 4
154
+ signedInfoAlg = nil
155
+ signedInfoData = nil
156
+ if signedInfoLength > 0
157
+ signedInfoEnd = offset + signedInfoLength
158
+ pstringData = readProtocolString(data,offset)
159
+ offset = offset + pstringData[0]
160
+ self.signedInfoAlg = pstringData[1]
161
+ self.signedInfoData = data[offset..-1]
162
+ offset = signedInfoEnd
163
+ end
164
+
165
+ end
166
+ end
167
+ def credential
168
+ @credential
169
+ end
170
+ def credentialType=(val)
171
+ @credentialType = val
172
+ end
173
+ def signedInfoAlg=(val)
174
+ @signedInfoAlg = val
175
+ end
176
+ def signedInfo=(val)
177
+ @signedInfo=val
178
+ end
179
+ def packet
180
+ @packet
181
+ end
182
+ def to_s
183
+ result = "opCode: " + opCode.to_s + "; responseCode: " + responseCode().to_s + " sessionId: " + fromBytes(@sessionId).to_s + "; requestId: " + fromBytes(@requestId).to_s + "; bodyLength: " + @bodyLength.to_s
184
+ if @bodyLength > 0
185
+ result = result + "; body: " + @packet[44...(44+@bodyLength)].pack('c*')
186
+ end
187
+ result
188
+ end
189
+ end
190
+ end
191
+ end
@@ -0,0 +1,46 @@
1
+ module Cul
2
+ module Handles
3
+ class ChallengeAnswerRequest < BaseRequest
4
+ include Hdl
5
+ def initialize(nonce,digest,keyHandle, keyIndex)
6
+ super()
7
+ @nonce = nonce
8
+ @digest =digest
9
+ @opCode = asBytes(OC_CHALLENGE_RESPONSE)
10
+ @authenticationType = toProtocolString("HS_SECKEY")
11
+ @keyHandle = toProtocolString(keyHandle)
12
+ @keyIndex = asBytes(keyIndex)
13
+ @challengeResponse = []
14
+ @secret = []
15
+ self.responseCode = 0
16
+ self.authoritative=false
17
+ self.returnRequestDigest=false
18
+ self.encrypt=false
19
+ self.publicOnly=false
20
+ self.certify=false
21
+ self.cacheCertify=true
22
+ self.recursive=true
23
+ self.continuous=false
24
+ self.keepAlive=false
25
+ self.expirationTime=0
26
+ end
27
+ def body()
28
+ @body
29
+ end
30
+ def secret=(val)
31
+ @secret = val.unpack('U*').pack('C*')
32
+ end
33
+ def encodeBody()
34
+ digest = Digest::SHA1.new()
35
+ digest.update(@secret)
36
+ digest.update(@nonce.pack('C*'))
37
+ digest.update(@digest.pack('C*'))
38
+ digest.update(@secret)
39
+ prehash = digest.digest()
40
+ @challengeResponse = [0x02].concat(prehash.unpack('C*'))
41
+ @challengeResponse = asBytes(@challengeResponse.length).concat(@challengeResponse)
42
+ @body = [].concat(@authenticationType).concat(@keyHandle).concat(@keyIndex).concat(@challengeResponse)
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,23 @@
1
+ module Cul
2
+ module Handles
3
+ class ChallengeResponse < BaseResponse
4
+ attr_reader :nonce, :digest
5
+ def parseBody(data)
6
+ # read digest
7
+ digestAlg = data[0]
8
+ if (digestAlg == 1)
9
+ @digest = data[1..16]
10
+ offset = 17
11
+ else
12
+ @digest = data[1..20]
13
+ offset = 21
14
+ end
15
+ arrayInfo = readByteArray(data,offset)
16
+ @nonce = arrayInfo[1]
17
+ end
18
+ def nonce
19
+ @nonce
20
+ end
21
+ end
22
+ end
23
+ end