Commit 76e326e5 authored by Renato Figueiro Maia's avatar Renato Figueiro Maia

[OPENBUS-2304] (Lua) Permitir fazer chamadas dentro de cadeias (join)...

[OPENBUS-2304] (Lua) Permitir fazer chamadas dentro de cadeias (join) recebidas com um login diferente, mas da mesma entidade
- Campo 'CallChain.target' passa a conter o 'EntityName' ao invés do 'LoginId'.
- A operação 'AccessControl:signChainFor(target)' passa a receber o 'EntityName'
  ao invés do 'LoginId', mas continua sem validar o valor do parâmetro 'target',
  simplesmente colocando o valor no campo 'CallChain.target' da cadeia gerada.
  Isso é necessário pra permitir assinar cadeias pra entidades deslogadas, que
  é importante pra permitir que um processo possa receber chamadas de entidades
  conhecidas (autenticadas previamente) mesmo sem ter acesso ao ACS. 
- Campo 'CredentialReset.login' passar a conter o 'EntityName' ao invés do
  'LoginId'. Esse campo também é renomeado pra 'CredentialReset.target' pra
  melhor clareza.
  - As sessões de saída não podem mais ter indexadas pelo 'LoginId' do destino
    (target), exatamente porque tal informação não vem mais no
    'CredentialReset'. Também não é razoável indexá-las pelo 'EntityName' pois
    potencialmente há multiplas instâncias da biblioteca de acesso (OpenBusLib)
    mantendo diferentes sessões com o mesmo 'EntityName' (assumiamos que o mesmo
    não acontecia com 'LoginId'), portanto quando uma instância da biblioteca
    conversasse com duas outras instâncias que usem o mesmo 'EntityName' a
    sessão de uma sobreporia a da outra concorrentemente degradando o desempenho
    podendo inclusive levar a uma situação de starvation em casos extremos.
    - A solução adotada foi indexar as sessões diretamente pelo
      'IOR.profile_data' do objeto sendo acessado. Antes fazíamos essa indexação
      de forma indireta através de dois mapas: um que mapeava 'IOR.profile_data'
      pra 'LoginId' e outro de 'LoginId' pra sessão. O intuito disso era
      diminuir o número de sessões a serem mantidas no cache.
- A forma de identificar se uma chamada está sendo feita a um objeto residente
  no núcleo do barramento (core) é feito comparando o 'CredentialReset.target'
  com o 'BusEntity' (nome da entidade que representa o núcleo do barramento).
	- Com isso, não é mais necessário padronizar o 'BusLogin' (login ID utilizado
		pelo núcleo do barramento). Inclusive o login ID utilizado pode ser o mesmo
    bus ID utilizado para diferenciar duas instâncias do barramento OpenBus.

git-svn-id: https://subversion.tecgraf.puc-rio.br/engdist/openbus/sdk/lua/branches/02_00_00@142237 ae0415b3-e90b-0410-900d-d0be9363c56b
parent caa3c3a9
......@@ -32,7 +32,6 @@ function hello:sayHello()
local chain = OpenBusContext:getCallerChain()
local entity = chain.caller.entity
log:TEST("got call from ",entity)
OpenBusContext:joinChain(chain)
-- define service properties
local searchprops = table.copy(properties)
......@@ -46,6 +45,7 @@ function hello:sayHello()
local entity = getprop(offer.properties, "openbus.offer.entity")
log:TEST("found service of ",entity,"!")
local hello = offer.service_ref:getFacetByName(iface.name):__narrow(iface)
OpenBusContext:joinChain(chain)
return hello:sayHello()
end
return "no service found!"
......
......@@ -54,7 +54,7 @@ local sysexthrow = require "openbus.util.sysex"
local libidl = require "openbus.idl"
local throw = libidl.throw
local coreidl = require "openbus.core.idl"
local BusLogin = coreidl.const.BusLogin
local BusEntity = coreidl.const.BusEntity
local EncryptedBlockSize = coreidl.const.EncryptedBlockSize
local CredentialContextId = coreidl.const.credential.CredentialContextId
local coresrvtypes = coreidl.types.services
......@@ -226,7 +226,7 @@ end
local function getCoreFacet(self, name, module)
return self.context.orb:narrow(self.bus:getFacetByName(name),
coresrvtypes[module][name])
coresrvtypes[module][name])
end
local function intiateLogin(self)
......@@ -354,13 +354,13 @@ function Connection:resetCaches()
self.signedChainOf = memoize(function(chain) return LRUCache() end, "k")
end
function Connection:signChainFor(remoteid, chain)
if remoteid == BusLogin then return chain end
function Connection:signChainFor(target, chain)
if target == BusEntity then return chain end
local access = self.AccessControl
local cache = self.signedChainOf[chain]
local joined = cache:get(remoteid)
local joined = cache:get(target)
while joined == nil do
joined = access:signChainFor(remoteid)
joined = access:signChainFor(target)
local login = getLogin(self)
if login == nil then
sysexthrow.NO_PERMISSION{
......@@ -370,10 +370,10 @@ function Connection:signChainFor(remoteid, chain)
end
cache = self.signedChainOf[chain]
if unmarshalChain(self, joined).caller.id == login.id then
cache:put(remoteid, joined)
cache:put(target, joined)
break
end
joined = cache:get(remoteid)
joined = cache:get(target)
end
return joined
end
......
......@@ -111,7 +111,7 @@ local function validateCredential(self, credential, login, request)
local hash = credential.hash
if hash ~= nil then
local chain = credential.chain
if chain == nil or chain.target == self.login.id then
if chain == nil or chain.target == self.login.entity then
-- get current credential session
local session = self.incomingSessions:rawget(credential.session)
if session ~= nil then
......@@ -168,7 +168,6 @@ function Context:__init()
idltypes[name] = types:lookup_id(repid)
end
self.types = idltypes
self.profile2login = LRUCache() -- [iop_profile] = loginid
self.callerChainOf = setmetatable({}, WeakKeys) -- [thread] = chain
self.joinedChainOf = setmetatable({}, WeakKeys) -- [thread] = chain
end
......@@ -261,7 +260,7 @@ function Interceptor:unmarshalCredential(contexts)
credential.chain = {
originators = originators,
caller = caller,
target = self.login.id,
target = self.login.entity,
}
return credential
end
......@@ -278,27 +277,21 @@ function Interceptor:sendrequest(request)
local chain = context.joinedChainOf[running()]
if chain==nil or chain.signature~=nil then -- no legacy chain (OpenBus 1.5)
local sessionid, ticket, hash = 0, 0, NullHash
local remoteid = context.profile2login:get(request.profile_data)
if remoteid ~= nil then -- known IOR profile, so it supports OpenBus 2.0
local session = self.outgoingSessions:get(request.profile_data)
if session ~= nil then -- credential session is established
legacy = nil -- do not send legacy credential (OpenBus 1.5)
chain = self:signChainFor(remoteid, chain or NullChain)
local session = self.outgoingSessions:get(remoteid)
if session ~= nil then -- credential session is established
sessionid = session.id
ticket = session.ticket+1
session.ticket = ticket
hash = calculateHash(session.secret, ticket, request)
log:access(self, msg.PerformBusCall:tag{
operation = request.operation_name,
remote = remoteid,
})
else
log:access(self, msg.ReinitiateCredentialSession:tag{
operation = request.operation_name,
})
end
chain = self:signChainFor(session.target, chain or NullChain)
sessionid = session.id
ticket = session.ticket+1
session.ticket = ticket
hash = calculateHash(session.secret, ticket, request)
log:access(self, msg.PerformBusCall:tag{
operation = request.operation_name,
remote = session.target,
})
else
log:access(self, msg.InitiateCredentialSession:tag{
chain = nil
log:access(self, msg.ReinitiateCredentialSession:tag{
operation = request.operation_name,
})
end
......@@ -349,16 +342,13 @@ function Interceptor:receivereply(request)
if secret ~= nil then
log:access(self, msg.GotCredentialReset:tag{
operation = request.operation_name,
remote = remoteid,
remote = reset.target,
})
reset.secret = secret
-- initialize session and set credential session information
local remoteid = reset.login
context.profile2login:put(request.profile_data, remoteid)
self.outgoingSessions:put(remoteid, {
self.outgoingSessions:put(request.profile_data, {
id = reset.session,
secret = reset.secret,
remoteid = remoteid,
secret = secret,
target = reset.target,
ticket = -1,
})
request.success = nil -- reissue request to the same reference
......@@ -431,7 +421,7 @@ function Interceptor:receiverequest(request, credential)
})
local encoder = context.orb:newencoder()
encoder:put({
login = self.login.id,
target = self.login.entity,
session = newsession.id,
challenge = challenge,
}, context.types.CredentialReset)
......
......@@ -18,7 +18,7 @@ local decodepubkey = pubkey.decodepublic
local idl = require "openbus.core.idl"
local loadIDL = idl.loadto
local BusLogin = idl.const.BusLogin
local BusEntity = idl.const.BusEntity
local EncryptedBlockSize = idl.const.EncryptedBlockSize
local CredentialContextId = idl.const.credential.CredentialContextId
local loginconst = idl.const.services.access_control
......@@ -186,7 +186,7 @@ function initBusSession(bus, login)
assert(ex.completed == "COMPLETED_NO")
assert(ex.minor == loginconst.InvalidCredentialCode)
local reset = decodeReset(assert(getrepcxt(CredentialContextId)), login.prvkey)
assert(reset.login == BusLogin)
assert(reset.target == BusEntity)
reset.ticket = 0
function reset:newCred(opname, chain)
local ticket = self.ticket+1
......@@ -289,12 +289,12 @@ function testBusCall(bus, login, otherkey, assertresults, proxy, opname, ...)
assert(ex.minor == loginconst.InvalidCredentialCode)
reset = decodeReset(assert(getrepcxt(CredentialContextId)), login.prvkey)
if bus.objects[proxy] then
assert(reset.login == BusLogin)
assert(reset.target == BusEntity)
chain = NullChain
else
assert(reset.login ~= BusLogin)
assert(reset.target ~= BusEntity)
login.busSession:newCred("signChainFor")
chain = bus.AccessControl:signChainFor(reset.login)
chain = bus.AccessControl:signChainFor(reset.target)
end
end
......@@ -404,7 +404,7 @@ function testBusCall(bus, login, otherkey, assertresults, proxy, opname, ...)
local newchain = NullChain
if not bus.objects[proxy] then
newlogin.busSession:newCred("signChainFor")
newchain = bus.AccessControl:signChainFor(reset.login)
newchain = bus.AccessControl:signChainFor(reset.target)
end
local credential = {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment