Hmm, one idea ad the ::routine problem introduced with ooRexx 5.0: how about adding a "securityManager" argument to the class methods creating instances of the Routine and Method classes? This way it should become possible to set the securityManager for the package to be built, making it possible again to get the requires checkpoint messages.

This would not be ideal IMHO, as it incurs the need of a change to existing code. But on the other hand existing code would not be able to intercept requires directives. New code would be able to take advantage of the new argument, making the security manager to work as designed also in the context of requires checkpoints.

---rony


On 13.11.2025 16:06, Rony G. Flatscher wrote:

Using basically the rexxref.pdf example in "Chapter 13. The Security Manager".

Here is the program ("agent.rex") that should run under the control of a 
security manager:

    /* Agent, cf. rexxref.pdf, "Chapter 13. The Security Manager */ "echo Hello 
There" -- a
    command call rxfuncadd "rxcalcsqrt", "rxmath", "rxcalcsqrt" -- external function say 
"result:"
    result -- access a variable call syssleep 0.5 -- external call line = 
linein("./profile") --
    access stream BIF say .error -- access .local say .methods -- access 
.environment
    .json~define("") -- access .environment t = .test~new -- access 
.context~package~local t~hello
    -- access an unprotected method t~myProtectedMethod -- access protected 
method ::requires
    json.cls -- about to require ::class test -- a Test class ::method 
"myProtectedMethod"
    protected -- can be supervised say self": method named" .context~name ::method 
"hello" --
    cannot be supervised say self": hello!"

The above program contains all the supervised operations including the requires directive for which rexxref.pdf states:

    "REQUIRES
    sent whenever a ::REQUIRES directive in the file is processed. The 
information directory contains
    the following entry:
    NAME
    The name of the file specified on the ::REQUIRES directive.
    When the REQUIRES method returns .false, indicating that it handled the 
request, the
    entry NAME in the information directory is used as the actual file to load 
for the request. The
    REQUIRES method can also provide a security manager to be used for the 
program loaded by
    the ::REQUIRES directive by setting the information directory entry 
SECURITYMANAGER to the
    desired security manager object."

However, it seems that the REQUIRES message gets never sent!

Here the code monitoring all messages that the security manager receives, using 
.routine's fromFile:

    parse arg program -- fetch program to run supervised 
routine=.Routine~newFile(program) --
    create routine object routine~setSecurityManager(.monitoringSupervisor~new) 
routine~call --
    execute program ::class monitoringSupervisor ::method unknown -- intercept 
all messages use
    arg methName, methArgs infoDir=methArgs[1] -- get the information directory 
call show
    methName,infoDir return .true -- let runtime execute operation ::routine 
show use arg name,
    dir str="" do idx over dir~allIndexes~sort if str="" then str= 
idx"='"dir[idx]"'" else
    str=str"," idx"='"dir[idx]"'" end say "checkpoint" left('"'name'" ',13,".") 
str

Here the code monitoring all messages that the seucrity manager receives, using .method's fromFile method:

    parse arg program -- fetch program to run supervised 
meth=.Method~newFile(program) -- create
    routine object meth~setSecurityManager(.monitoringSupervisor~new) 
.Agent~new(meth) -- execute
    program ::class agent -- class to allow sueprvised method to run ::method 
init use arg meth --
    fetch method object self~run(meth) -- run method object ::class 
monitoringSupervisor ::method
    unknown -- intercept all messages use arg methName, methArgs 
infoDir=methArgs[1] -- get the
    information directory call show methName,infoDir return .true -- let 
runtime execute operation
    ::routine show use arg name, dir str="" do idx over dir~allIndexes~sort if 
str="" then str=
    idx"='"dir[idx]"'" else str=str"," idx"='"dir[idx]"'" end say "checkpoint" 
left('"'name'"
    ',13,".") str

Running either with the following command their output gives:

    E:\WU\securityManager>*monitorAsRoutine.rex agent.rex*
    checkpoint*"COMMAND"* ... ADDRESS='CMD', COMMAND='echo Hello There'
    result: 0
    checkpoint*"CALL"* ...... ARGUMENTS='0.5', NAME='SYSSLEEP'
    checkpoint*"STREAM"* .... 
NAME='E:\WU\Lehrveranstaltungen\Materialien\BP1_AutoWin\090_ooRexx_advanced_code\securityManager\profile'
    checkpoint*"LOCAL"* ..... NAME='ERROR'
    The ERROR monitor
    checkpoint*"LOCAL"* ..... NAME='METHODS'
    checkpoint*"ENVIRONMENT"* NAME='METHODS'
    .METHODS
    checkpoint*"METHOD"* .... ARGUMENTS='', NAME='DEFINE', OBJECT='The JSON 
class'
    a TEST: hello!
    checkpoint*"METHOD"* .... ARGUMENTS='', NAME='MYPROTECTEDMETHOD', OBJECT='a 
TEST'

    E:\WU\securityManager>*monitorAsMethod.rex agent.rex*
    checkpoint*"COMMAND"* ... ADDRESS='CMD', COMMAND='echo Hello There'
    result: 0
    checkpoint*"CALL"* ...... ARGUMENTS='0.5', NAME='SYSSLEEP'
    checkpoint*"STREAM"* .... 
NAME='E:\WU\Lehrveranstaltungen\Materialien\BP1_AutoWin\090_ooRexx_advanced_code\securityManager\profile'
    checkpoint*"LOCAL"* ..... NAME='ERROR'
    The ERROR monitor
    checkpoint*"LOCAL"* ..... NAME='METHODS'
    checkpoint*"ENVIRONMENT"* NAME='METHODS'
    .METHODS
    checkpoint*"METHOD"* .... ARGUMENTS='', NAME='DEFINE', OBJECT='The JSON 
class'
    a TEST: hello!
    checkpoint*"METHOD"* .... ARGUMENTS='', NAME='MYPROTECTEDMETHOD', OBJECT='a 
TEST'

Unlike all other security manager methods, the security manager method "REQUIRES" never gets triggered!

Is there a solution to this problem, and if so, what would it be?

---rony


_______________________________________________
Oorexx-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/oorexx-devel

Reply via email to