cul-handles 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/VERSION +1 -1
- data/cul-handles.gemspec +79 -0
- data/lib/cul/handles/base_message.rb +121 -0
- data/lib/cul/handles/base_request.rb +153 -0
- data/lib/cul/handles/base_response.rb +191 -0
- data/lib/cul/handles/challenge_answer_request.rb +46 -0
- data/lib/cul/handles/challenge_response.rb +23 -0
- data/lib/cul/handles/client.rb +113 -0
- data/lib/cul/handles/create_handle_request.rb +22 -0
- data/lib/cul/handles/delete_handle_request.rb +22 -0
- data/lib/cul/handles/delete_value_request.rb +14 -0
- data/lib/cul/handles/handle_value_request.rb +90 -0
- data/lib/cul/handles/hdl.rb +244 -0
- data/lib/cul/handles/modify_value_request.rb +10 -0
- data/lib/cul/handles/resolution_request.rb +31 -0
- data/lib/cul/handles/resolution_response.rb +168 -0
- data/lib/cul/handles/session_request.rb +126 -0
- data/lib/cul/handles/session_setup_response.rb +25 -0
- data/lib/cul/handles/set_value_request.rb +6 -0
- metadata +24 -2
@@ -0,0 +1,113 @@
|
|
1
|
+
module Cul
|
2
|
+
module Handles
|
3
|
+
class Client
|
4
|
+
include Hdl
|
5
|
+
DEFAULT_ADMIN = "10022/ADMIN"
|
6
|
+
def initialize(server,port,admin=DEFAULT_ADMIN)
|
7
|
+
@server = server
|
8
|
+
@port = port
|
9
|
+
@admin = admin
|
10
|
+
@debug = false
|
11
|
+
end
|
12
|
+
def debug=(val)
|
13
|
+
if(val)
|
14
|
+
@debug = true
|
15
|
+
else
|
16
|
+
@debug = false
|
17
|
+
end
|
18
|
+
end
|
19
|
+
def initRequest(request)
|
20
|
+
now = Time.new
|
21
|
+
request.requestId= now.to_i
|
22
|
+
request.expirationTime=(Time.new().to_i + 600) # 10 minutes
|
23
|
+
return request
|
24
|
+
end
|
25
|
+
def resolve(handle)
|
26
|
+
sock = TCPSocket.new(@server,@port)
|
27
|
+
req = ResolutionRequest.new(handle)
|
28
|
+
req.publicOnly=true
|
29
|
+
req.authoritative=true
|
30
|
+
req.keepAlive=false
|
31
|
+
req.siteInfoSerial=-1
|
32
|
+
req.sequenceNumber=1
|
33
|
+
now = Time.new
|
34
|
+
req.requestId=((now.to_i * 1000000) + (now.usec % 1000))
|
35
|
+
req.expirationTime=0
|
36
|
+
req.sessionId= 0 #get new res.sessionId
|
37
|
+
res = ResolutionResponse.new()
|
38
|
+
res.send(req,sock)
|
39
|
+
if (@debug)
|
40
|
+
puts "Resolution Request sent"
|
41
|
+
puts("used sessionId: " + res.sessionId.to_s + "; requestId: " + res.requestId.to_s)
|
42
|
+
puts("response code: " + res.responseCode.to_s)
|
43
|
+
end
|
44
|
+
sock.close()
|
45
|
+
return res
|
46
|
+
end
|
47
|
+
def createHandle(adminSecret,handle,url=nil)
|
48
|
+
req = Cul::Handles::CreateHandleRequest.new(handle)
|
49
|
+
initRequest(req)
|
50
|
+
req.addAdminValue(@admin, PERM_ALL, 100)
|
51
|
+
if not url.nil?
|
52
|
+
req.addURLValue(url)
|
53
|
+
end
|
54
|
+
return sendAuthRequest(req, adminSecret)
|
55
|
+
end
|
56
|
+
def createAdminHandle(adminSecret, newHandle, newHandleSecret)
|
57
|
+
req = Cul::Handles::CreateHandleRequest.new(newHandle)
|
58
|
+
initRequest(req)
|
59
|
+
req.addAdminValue(DEFAULT_ADMIN, PERM_ALL, 100)
|
60
|
+
req.addSecretKeyValue(newHandleSecret)
|
61
|
+
return sendAuthRequest(req, adminSecret)
|
62
|
+
end
|
63
|
+
def deleteHandle(adminSecret,handle)
|
64
|
+
req = Cul::Handles::DeleteHandleRequest.new(handle)
|
65
|
+
initRequest(req)
|
66
|
+
return sendAuthRequest(req, adminSecret)
|
67
|
+
end
|
68
|
+
def addHandleValue(adminSecret,handle,url)
|
69
|
+
req = Cul::Handles::AddValueRequest.new(handle)
|
70
|
+
req.addURLValue(url)
|
71
|
+
initRequest(req)
|
72
|
+
return sendAuthRequest(req, adminSecret)
|
73
|
+
end
|
74
|
+
def changeHandleValue(adminSecret, handle, url)
|
75
|
+
req = Cul::Handles::ModifyValueRequest.new(handle)
|
76
|
+
req.addURLValue(url)
|
77
|
+
initRequest(req)
|
78
|
+
return sendAuthRequest(req, adminSecret)
|
79
|
+
end
|
80
|
+
def addHandleMaintainer(adminSecret,handle,maintainerHandle)
|
81
|
+
req = Cul::Handles::AddValueRequest.new(handle)
|
82
|
+
req.addAdminValue(maintainerHandle, 0x0070, INDEX_MAINTAINER_HANDLE)
|
83
|
+
initRequest(req)
|
84
|
+
return sendAuthRequest(req, adminSecret)
|
85
|
+
end
|
86
|
+
def deleteHandleValue(adminSecret, handle, url)
|
87
|
+
req = Cul::Handles::DeleteValueRequest.new(handle)
|
88
|
+
req.addURLValue(url)
|
89
|
+
initRequest(req)
|
90
|
+
return sendAuthRequest(req, adminSecret)
|
91
|
+
end
|
92
|
+
def sendAuthRequest(request, adminSecret)
|
93
|
+
res = ChallengeResponse.new()
|
94
|
+
sock = TCPSocket.new(@server,@port)
|
95
|
+
res.send(request, sock)
|
96
|
+
sock.close()
|
97
|
+
if not (res.responseCode.eql?RC_AUTHEN_NEEDED)
|
98
|
+
raise "Unexpected server challenge rcode: " + res.responseCode.to_s
|
99
|
+
end
|
100
|
+
creq = ChallengeAnswerRequest.new(res.nonce,res.digest,@admin,INDEX_AUTH)
|
101
|
+
creq.sessionId = res.sessionId
|
102
|
+
initRequest(creq)
|
103
|
+
creq.requestId= request.requestId + 1
|
104
|
+
creq.secret=(adminSecret)
|
105
|
+
cres = BaseResponse.new()
|
106
|
+
sock = TCPSocket.new(@server,@port)
|
107
|
+
cres.send(creq, sock)
|
108
|
+
sock.close()
|
109
|
+
return cres
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Cul
|
2
|
+
module Handles
|
3
|
+
class CreateHandleRequest < HandleValueRequest
|
4
|
+
def initialize(handle)
|
5
|
+
super()
|
6
|
+
@opCode = asBytes(Hdl::OC_CREATE_HANDLE)
|
7
|
+
end
|
8
|
+
def valid?
|
9
|
+
if not @handle
|
10
|
+
return false
|
11
|
+
end
|
12
|
+
@values.each { |value|
|
13
|
+
if value.type == "HS_ADMIN"
|
14
|
+
return true
|
15
|
+
end
|
16
|
+
}
|
17
|
+
return false
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Cul
|
2
|
+
module Handles
|
3
|
+
class DeleteHandleRequest < BaseRequest
|
4
|
+
include Hdl
|
5
|
+
def initialize(handle)
|
6
|
+
super()
|
7
|
+
@opCode = asBytes(Hdl::OC_DELETE_HANDLE)
|
8
|
+
self.responseCode = 0
|
9
|
+
@handle = toProtocolString(handle)
|
10
|
+
end
|
11
|
+
def valid?
|
12
|
+
if not @handle
|
13
|
+
return false
|
14
|
+
end
|
15
|
+
return true
|
16
|
+
end
|
17
|
+
def encodeBody
|
18
|
+
@body = @handle
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Cul
|
2
|
+
module Handles
|
3
|
+
class RemoveValueRequest < BaseRequest
|
4
|
+
include Hdl
|
5
|
+
def initialize(handle)
|
6
|
+
super()
|
7
|
+
@opCode = asBytes(OC_REMOVE_VALUE)
|
8
|
+
self.responseCode = 0
|
9
|
+
@handle = toProtocolString(handle)
|
10
|
+
@values = []
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module Cul
|
2
|
+
module Handles
|
3
|
+
class HandleValueRequest < BaseRequest
|
4
|
+
ADMIN_ONLY = HandleValue::PERM_ADMIN_READ & HandleValue::PERM_ADMIN_WRITE
|
5
|
+
def initialize(handle)
|
6
|
+
super()
|
7
|
+
self.responseCode = 0
|
8
|
+
self.certify=true
|
9
|
+
self.authoritative=true
|
10
|
+
self.returnRequestDigest=(true)
|
11
|
+
@handle = toProtocolString(handle)
|
12
|
+
@values = []
|
13
|
+
end
|
14
|
+
def addURLValue(urlValue)
|
15
|
+
# serialize handle value
|
16
|
+
value = HandleValue.new()
|
17
|
+
value.data = urlValue.unpack('U*')
|
18
|
+
value.type = "URL".unpack('U*')
|
19
|
+
value.index = asBytes(1) # is this a default?
|
20
|
+
@values.push(value)
|
21
|
+
end
|
22
|
+
def addAdminValue(adminHandle, permissions, index=INDEX_ADMIN_HANDLE)
|
23
|
+
value = HandleValue.new()
|
24
|
+
value.data=value.encodeAdminData(adminHandle, permissions, INDEX_AUTH)
|
25
|
+
value.type = "HS_ADMIN".unpack('U*')
|
26
|
+
value.index = asBytes(index) # is this a default?
|
27
|
+
@values.push(value)
|
28
|
+
end
|
29
|
+
def addSecretKeyValue(secret)
|
30
|
+
value = HandleValue.new()
|
31
|
+
value.data=secret.unpack('U*')
|
32
|
+
|
33
|
+
value.type="HS_SECKEY".unpack('U*')
|
34
|
+
value.perm=(ADMIN_ONLY)
|
35
|
+
value.index = asBytes(INDEX_AUTH)
|
36
|
+
@values.push(value)
|
37
|
+
end
|
38
|
+
def encodeBody
|
39
|
+
result = [].concat(@handle)
|
40
|
+
result.concat(asBytes(@values.length))
|
41
|
+
@values.each {|value|
|
42
|
+
#puts value.serialize.join unless value.nil?
|
43
|
+
result.concat(value.serialize)
|
44
|
+
}
|
45
|
+
@body = result
|
46
|
+
end
|
47
|
+
end
|
48
|
+
class CreateHandleRequest < HandleValueRequest
|
49
|
+
def initialize(handle)
|
50
|
+
super(handle)
|
51
|
+
@opCode = asBytes(Hdl::OC_CREATE_HANDLE)
|
52
|
+
end
|
53
|
+
def valid?
|
54
|
+
if not @handle
|
55
|
+
return false
|
56
|
+
end
|
57
|
+
@values.each { |value|
|
58
|
+
if value.type == "HS_ADMIN"
|
59
|
+
return true
|
60
|
+
end
|
61
|
+
}
|
62
|
+
return false
|
63
|
+
end
|
64
|
+
end
|
65
|
+
class AddValueRequest < HandleValueRequest
|
66
|
+
def initialize(handle)
|
67
|
+
super(handle)
|
68
|
+
@opCode = asBytes(Hdl::OC_ADD_VALUE)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
class ModifyValueRequest < HandleValueRequest
|
72
|
+
def initialize(handle)
|
73
|
+
super(handle)
|
74
|
+
@opCode = asBytes(Hdl::OC_MODIFY_VALUE)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
class DeleteValueRequest < HandleValueRequest
|
78
|
+
def initialize(handle)
|
79
|
+
super(handle)
|
80
|
+
@opCode = asBytes(Hdl::OC_REMOVE_VALUE)
|
81
|
+
end
|
82
|
+
def addAdminValue(adminHandle, permissions, index)
|
83
|
+
if (index.eql?(100))
|
84
|
+
raise "Deleting the admin value would leave the handle without an administrator; Use modify value instead."
|
85
|
+
end
|
86
|
+
super(adminHandle, permissions, index)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,244 @@
|
|
1
|
+
module Cul
|
2
|
+
module Handles
|
3
|
+
module Hdl
|
4
|
+
# OpFlag masks
|
5
|
+
MSG_FLAG_AUTH = 0x80 # don't use cache, use only primaries
|
6
|
+
MSG_FLAG_CERT = 0x40 # asks server to sign responses
|
7
|
+
MSG_FLAG_ENCR = 0x20 # asks server to encrypt responses
|
8
|
+
MSG_FLAG_RECU = 0x10 # server should try and resolve handle if not found
|
9
|
+
MSG_FLAG_CACR = 0x08 # responses should be signed by cache
|
10
|
+
MSG_FLAG_CONT = 0x04 # there are more parts to this message
|
11
|
+
MSG_FLAG_KPAL = 0x02 # keep the socket open for more requests
|
12
|
+
MSG_FLAG_PUBL = 0x01 # resolution requests should only return public vals
|
13
|
+
MSG_FLAG_RRDG = 0x80 # responses should include a digest of the request
|
14
|
+
MSG_FLAG_AUTH_INDEX = 0
|
15
|
+
MSG_FLAG_CERT_INDEX = 0
|
16
|
+
MSG_FLAG_ENCR_INDEX = 0
|
17
|
+
MSG_FLAG_RECU_INDEX = 0
|
18
|
+
MSG_FLAG_CACR_INDEX = 0
|
19
|
+
MSG_FLAG_CONT_INDEX = 0
|
20
|
+
MSG_FLAG_KPAL_INDEX = 0
|
21
|
+
MSG_FLAG_PUBL_INDEX = 0
|
22
|
+
MSG_FLAG_RRDG_INDEX = 1
|
23
|
+
# MessageFlag masks
|
24
|
+
ENV_FLAG_COMPRESSED = 0x80
|
25
|
+
ENV_FLAG_ENCRYPTED = 0x40
|
26
|
+
ENV_FLAG_TRUNCATED = 0x20
|
27
|
+
# OpCode values
|
28
|
+
OC_RESERVED = 0
|
29
|
+
OC_RESOLUTION = 1
|
30
|
+
OC_GET_SITEINFO = 2
|
31
|
+
OC_CREATE_HANDLE = 100
|
32
|
+
OC_DELETE_HANDLE = 101
|
33
|
+
OC_ADD_VALUE = 102
|
34
|
+
OC_REMOVE_VALUE = 103
|
35
|
+
OC_MODIFY_VALUE = 104
|
36
|
+
OC_LIST_HANDLE = 105
|
37
|
+
OC_LIST_NA = 106
|
38
|
+
OC_CHALLENGE_RESPONSE = 200
|
39
|
+
OC_VERIFY_RESPONSE = 201
|
40
|
+
OC_SESSION_SETUP = 400
|
41
|
+
OC_SESSION_TERMINATE = 401
|
42
|
+
OC_SESSION_EXCHANGEKEY = 402
|
43
|
+
# ResponseCode values
|
44
|
+
RC_RESERVED = 0
|
45
|
+
RC_SUCCESS = 1
|
46
|
+
RC_ERROR = 2
|
47
|
+
RC_SERVER_BUSY = 3
|
48
|
+
RC_PROTOCOL_ERROR = 4
|
49
|
+
RC_OPERATION_DENIED = 5
|
50
|
+
RC_RECUR_LIMIT_EXCEEDED = 6
|
51
|
+
RC_HANDLE_NOT_FOUND = 100
|
52
|
+
RC_HANDLE_ALREADY_EXIST = 101
|
53
|
+
RC_INVALID_HANDLE = 102
|
54
|
+
RC_VALUE_NOT_FOUND = 200
|
55
|
+
RC_VALUE_ALREADY_EXIST = 201
|
56
|
+
RC_VALUE_INVALID = 202
|
57
|
+
RC_EXPIRED_SITE_INFO = 300
|
58
|
+
RC_SERVER_NOT_RESP = 301
|
59
|
+
RC_SERVICE_REFERRAL = 302
|
60
|
+
RC_NA_DELEGATE = 303
|
61
|
+
RC_NOT_AUTHORIZED = 400
|
62
|
+
RC_ACCESS_DENIED = 401
|
63
|
+
RC_AUTHEN_NEEDED = 402
|
64
|
+
RC_AUTHEN_FAILED = 403
|
65
|
+
RC_INVALID_CREDENTIAL = 404
|
66
|
+
RC_AUTHEN_TIMEOUT = 405
|
67
|
+
RC_UNABLE_TO_AUTHEN = 406
|
68
|
+
RC_SESSION_TIMEOUT = 500
|
69
|
+
RC_SESSION_FAILED = 501
|
70
|
+
RC_NO_SESSION_KEY = 502
|
71
|
+
RC_SESSION_NO_SUPPORT = 503
|
72
|
+
RC_SESSION_KEY_INVALID = 504
|
73
|
+
RC_TRYING = 900
|
74
|
+
RC_FORWARDED = 901
|
75
|
+
RC_QUEUED = 902
|
76
|
+
# handle value admin permissions
|
77
|
+
PERM_ADD_HANDLE = 0x0001;
|
78
|
+
PERM_DELETE_HANDLE = 0x0002;
|
79
|
+
PERM_ADD_NA = 0x0004;
|
80
|
+
PERM_DELETE_NA = 0x0008;
|
81
|
+
PERM_MODIFY_VALUE = 0x0010;
|
82
|
+
PERM_REMOVE_VALUE = 0x0020;
|
83
|
+
PERM_ADD_VALUE = 0x0040;
|
84
|
+
PERM_MODIFY_ADMIN = 0x0080;
|
85
|
+
PERM_REMOVE_ADMIN = 0x0100;
|
86
|
+
PERM_ADD_ADMIN = 0x0200;
|
87
|
+
PERM_READ_VALUE = 0x0400;
|
88
|
+
PERM_LIST_HDLS = 0x0800;
|
89
|
+
PERM_ALL = 0x0fff;
|
90
|
+
# standard handle indices
|
91
|
+
INDEX_ADMIN_HANDLE = 100 # index for create/delete/super admin
|
92
|
+
INDEX_MAINTAINER_HANDLE = 101 # index for modify/update admin
|
93
|
+
INDEX_AUTH = 300 # index of HS_SECKEY value
|
94
|
+
class UnsignedInt
|
95
|
+
def UnsignedInt.asBytes(val)
|
96
|
+
[(val&0xff000000)>>24, (val&0xff0000)>>16, (val&0xff00)>>8, val&0xff]
|
97
|
+
end
|
98
|
+
def UnsignedInt.fromBytes(data)
|
99
|
+
result = data[-1]
|
100
|
+
for i in ((data.length-1)..1)
|
101
|
+
result |= (data[i] << (8*i))
|
102
|
+
end
|
103
|
+
return result
|
104
|
+
end
|
105
|
+
end
|
106
|
+
class UnsignedShort
|
107
|
+
def UnsignedShort.asBytes(val)
|
108
|
+
[(val&0xff00)>>8, val&0xff]
|
109
|
+
end
|
110
|
+
def UnsignedShort.fromBytes(data)
|
111
|
+
result = data[-1]
|
112
|
+
for i in ((data.length-1)..1)
|
113
|
+
result |= (data[i] << (8*i))
|
114
|
+
end
|
115
|
+
return result
|
116
|
+
end
|
117
|
+
end
|
118
|
+
class UnsignedByte
|
119
|
+
def UnsignedByte.asBytes(val)
|
120
|
+
[val&0xff]
|
121
|
+
end
|
122
|
+
def UnsignedByte.fromBytes(data)
|
123
|
+
if data.to_i == data
|
124
|
+
mask = data
|
125
|
+
else
|
126
|
+
mask = data[0]
|
127
|
+
end
|
128
|
+
result = 0
|
129
|
+
if mask & 0x01 == 0x01
|
130
|
+
result = result + 1
|
131
|
+
end
|
132
|
+
if mask & 0x02 == 0x02
|
133
|
+
result = result + 2
|
134
|
+
end
|
135
|
+
if mask & 0x04 == 0x04
|
136
|
+
result = result + 4
|
137
|
+
end
|
138
|
+
if mask & 0x08 == 0x08
|
139
|
+
result = result + 8
|
140
|
+
end
|
141
|
+
if mask & 0x10 == 0x10
|
142
|
+
result = result + 16
|
143
|
+
end
|
144
|
+
if mask & 0x20 == 0x20
|
145
|
+
result = result + 32
|
146
|
+
end
|
147
|
+
if mask & 0x40 == 0x40
|
148
|
+
result = result + 64
|
149
|
+
end
|
150
|
+
if mask & 0x80 == 0x80
|
151
|
+
result = result + 128
|
152
|
+
end
|
153
|
+
return result
|
154
|
+
end
|
155
|
+
end
|
156
|
+
def asBytes(val)
|
157
|
+
[(val&0xff000000)>>24,(val&0xff0000)>>16,(val&0xff00)>>8,val&0xff]
|
158
|
+
end
|
159
|
+
def fromBytes(data)
|
160
|
+
if(data.nil?)
|
161
|
+
return 0
|
162
|
+
end
|
163
|
+
result = 0
|
164
|
+
shift = data.length - 1
|
165
|
+
data.each{|byte|
|
166
|
+
digit = UnsignedByte.fromBytes(byte)
|
167
|
+
result = result + (digit << (8*shift))
|
168
|
+
shift = shift - 1
|
169
|
+
}
|
170
|
+
return result
|
171
|
+
end
|
172
|
+
def toProtocolString(data)
|
173
|
+
dataBytes = data.unpack('U*').pack('U*').unpack('C*')
|
174
|
+
length = dataBytes.length
|
175
|
+
result = asBytes(length)
|
176
|
+
result.concat(dataBytes)
|
177
|
+
return result
|
178
|
+
end
|
179
|
+
def readProtocolString(data,offset=0)
|
180
|
+
octetsRead = 4
|
181
|
+
length = fromBytes(data[offset...offset+4])
|
182
|
+
pstring = ""
|
183
|
+
if length > 0
|
184
|
+
pstring = data[offset+4...offset+4+length].pack('C*')
|
185
|
+
octetsRead = octetsRead + length
|
186
|
+
end
|
187
|
+
return [octetsRead,pstring]
|
188
|
+
end
|
189
|
+
def readByteArray(data,offset=0)
|
190
|
+
bytes = fromBytes(data[offset...offset+4])
|
191
|
+
octetsRead = 4 + bytes
|
192
|
+
start = offset + 4
|
193
|
+
result = data[start...(start+bytes)]
|
194
|
+
return [octetsRead,result]
|
195
|
+
end
|
196
|
+
def readIntArray(data,offset=0)
|
197
|
+
ints = fromBytes(data[offset...offset+4])
|
198
|
+
octetsRead = 4 + (4*ints)
|
199
|
+
start = offset + 4
|
200
|
+
result = data[start...(offset+octetsRead)]
|
201
|
+
return [octetsRead,result]
|
202
|
+
end
|
203
|
+
def calculateValueLen(values,offset=0)
|
204
|
+
origOffset = offset
|
205
|
+
offset = offset + 14 # index - 4 bytes; timestamp - 4 bytes; ttlType - 1 byte; ttl - 4 bytes; permissions - 1 byte
|
206
|
+
|
207
|
+
fieldLen = fromBytes( values[offset...offset+4]) # type field
|
208
|
+
offset = offset + 4 + fieldLen
|
209
|
+
|
210
|
+
fieldLen = fromBytes( values[offset...offset+4]) # data field
|
211
|
+
offset = offset + 4 + fieldLen
|
212
|
+
|
213
|
+
fieldLen = fromBytes( values[offset...offset+4]) # references (number of)
|
214
|
+
offset = offset + 4 + fieldLen
|
215
|
+
|
216
|
+
for i in (1..fieldLen) # each reference - hdl length + hdl + index
|
217
|
+
refLen = fromBytes( values[offset...offset+4])
|
218
|
+
offset = offset + 4 + refLen + 4
|
219
|
+
end
|
220
|
+
return offset - origOffset
|
221
|
+
end
|
222
|
+
def decodeAdminData(data)
|
223
|
+
permissions = fromBytes(data[0..1])
|
224
|
+
arrayInfo = readByteArray(data[2...-1])
|
225
|
+
offset = 2 + arrayInfo[0]
|
226
|
+
adminHandle = arrayInfo[1].pack('U*')
|
227
|
+
index = fromBytes(data[offset..offset+3])
|
228
|
+
return {'permissions' => permissions, 'handle' => adminHandle, 'index' => index}
|
229
|
+
end
|
230
|
+
def encodeAdminData(adminHandle, permissions, index)
|
231
|
+
result = asBytes(permissions)[2..3]
|
232
|
+
hbytes = adminHandle.unpack('U*')
|
233
|
+
result.concat(asBytes(hbytes.length))
|
234
|
+
result.concat(hbytes)
|
235
|
+
result.concat(asBytes(index))
|
236
|
+
result
|
237
|
+
end
|
238
|
+
def convert16t8(data)
|
239
|
+
# first split into bytes
|
240
|
+
[]
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Cul
|
2
|
+
module Handles
|
3
|
+
class ResolutionRequest < BaseRequest
|
4
|
+
def initialize(handle)
|
5
|
+
super()
|
6
|
+
@opCode = asBytes(OC_RESOLUTION)
|
7
|
+
self.responseCode = 0
|
8
|
+
self.authoritative=false
|
9
|
+
self.returnRequestDigest=false
|
10
|
+
self.encrypt=false
|
11
|
+
self.publicOnly=false
|
12
|
+
self.certify=false
|
13
|
+
self.cacheCertify=true
|
14
|
+
self.recursive=true
|
15
|
+
self.continuous=false
|
16
|
+
self.keepAlive=false
|
17
|
+
self.expirationTime=0
|
18
|
+
@handle = toProtocolString(handle)
|
19
|
+
end
|
20
|
+
def encodeBody()
|
21
|
+
@body= [].concat(@handle).concat(self.indexList).concat(self.typeList)
|
22
|
+
end
|
23
|
+
def indexList
|
24
|
+
[0,0,0,0] # return all indices
|
25
|
+
end
|
26
|
+
def typeList
|
27
|
+
[0,0,0,0] # return all types
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|