MarcJHuber/event-driven-servers

tac_plus-ng - CLI context aware - unclear documentation

jakunow opened this issue · 3 comments

Hi,

According to documentation tac_plus-ng is "CLI context aware". My understanding is that it can perform command authorization based on what section of configuration user currently is changing i.e. user in (config) after previously typing "config t"

I'm unable to achieve this in configuration, tried using following code in script:

                                if (context == "config") {
                                        if (cmd =~ /^logging/) permit
                                        deny
                                }
                                deny

but DEBUG logs don't show that context == "config" condition is even evaluated.

I'm using version 990f07d

Hi,

the "context" feature can be used to "remember" nested configurations. The best example is likely interface context. From memory:

# permit shut/no shut for eth0:
if (cmd == /^interface Ethernet0/) {
    context = "mayShutdown"
    permit
}
if (cmd == /^interface /) {
   context = ""
}
if (context == "mayShutdown") {
    if (cmd == /^(no )?shutdown/")
        permit
}

Typically, exec and config commands don't overlap, but sure, you could use "if (cmd = /^configure terminal/) set context = ..." the very same way.

Vendors could easily provide the nested configuration path (plus the exec/config mode) as additional arguments for evaluation, that would avoid that hack (and wouldn't even require single-connection). Alas, nowadays the focus has shifted away from CLI configuration towards OpenConfig/REST/Cloud, so I wouldn't expect anything.

Cheers,

Marc

Hi,

Tried to use this approach but it doesn't seem to be working. According to debug log if (context == "<STRING>")is never even evaluated, setting of context also produces debug log suggesting it might not work

Possibly no single-connection support. Context feature may or may not work.

Relevant configuration bit:

if (cmd =~ / ^ config /) {
    context = "config"
    permit
}
if (context == "config") {
    if (cmd =~ / ^ logging / ) permit
    deny
}
deny

Relevant logging messages when running config t:

pcre2: '^config' <=> 'configure terminal' = 1
 line 268: [cmd] <pcre-regex> '^config' => true
        Possibly no single-connection support. Context feature may or may not work.
 line 269: [context]
 line 270: [permit]
Writing AUTHOR/PASS_ADD size=18

Relevant logging messages when running logging severity warning inside config context:

 line 268: [cmd] <pcre-regex> '^config' => false
 line 276: [deny]

Hi Jakub,

single-connection mode is required for the context feature to work. I just did a quick test, it's working just fine:

# telnet 10.0.0.1
Trying 10.0.0.1...
Connected to 10.0.0.1.
Escape character is '^]'.

Welcome
Username: demo
Password:

router#conf t
Enter configuration commands, one per line.  End with CNTL/Z.
router(config)#int fa0/0
context is Fa0/0

router(config-if)#no shut
router(config-if)#int fa0/1
context was reset

router(config-if)#no shut
Command authorization failed.

router(config-if)#exit
router(config)#exit
router#exit
Connection closed by foreign host.
id = spawnd {
        listen { port = 49 }
}

id = tac_plus-ng {
        device world {
                address = ::/0
                welcome banner = "Welcome\n"
                key = demo
        }

        profile demo {
                script {
                        if (service == shell) {
                                    if (cmd == "") {
                                        set priv-lvl = 15
                                        permit
                                    }
                                    if (cmd =~ /^interface FastEthernet 0\/0 <cr>/) {
                                        context = Fa0/0
                                        message = "context is Fa0/0"
                                        permit
                                    }
                                    if (cmd =~ /^interface/) {
                                        context = ""
                                        message = "context was reset"
                                    }
                                    if (cmd =~ /^(no )?shutdown/) {
                                        if (context == Fa0/0)
                                                permit
                                        deny
                                    }
                                    permit
                        }
                }
        }

        user demo {
                password login = clear demo
        }

        ruleset {
                rule demo {
                        script {
                                profile = demo
                                permit
                        }
                }
        }
}

Cheers,

Marc