* NACM extension (RFC8341)

* NACM module support (RFC8341 A1+A2)
   * Recovery user "_nacm_recovery" added.
     * Example use is restconf PUT when NACM edit-config is permitted, then automatic commit and discard are permitted using recovery user.
   * Example user changed adm1 to andy to comply with RFC8341 example

 * Yang code upgrade (RFC7950)
   * RPC method input parameters validated
     * see https://github.com/clicon/clixon/issues/4
* Correct XML namespace handling
   * XML multiple modules was based on "loose" semantics so that yang modules were found by iterating thorugh namespaces until a match was made. This did not adhere to proper [XML namespace handling](https://www.w3.org/TR/2009/REC-xml-names-20091208), and causes problems with overlapping names and false positives. Below see XML accepted (but wrong), and correct namespace declaration:
```
      <rpc><my-own-method></rpc> # Wrong but accepted
      <rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> # Correct
        <my-own-method xmlns="http://example.net/me/my-own/1.0">
      </rpc>
```
   * To keep old loose semantics set config option CLICON_XML_NS_ITERATE (true by default)
   * XML to JSON translator support for mapping xmlns attribute to module name prefix.
   * Default namespace is still "urn:ietf:params:xml:ns:netconf:base:1.0"
   * See https://github.com/clicon/clixon/issues/49
* Changed all make tags --> make TAGS
* Keyvalue datastore removed (it has been disabled since 3.3.3)
* debug rpc added in example application (should be in clixon-config).
This commit is contained in:
Olof hagsand 2018-12-16 19:46:26 +01:00
parent e5c0b06cf9
commit ae1af8da9e
63 changed files with 1852 additions and 3492 deletions

View file

@ -7,6 +7,7 @@
APPNAME=example
# include err() and new() functions and creates $dir
. ./lib.sh
. ./nacm.sh
cfg=$dir/conf_yang.xml
fyang=$dir/test.yang
@ -40,7 +41,12 @@ cat <<EOF > $fyang
module $APPNAME{
yang-version 1.1;
namespace "urn:example:clixon";
prefix ex;
import ietf-routing {
description "For fib-route";
prefix rt;
}
container authentication {
description "Example code for enabling www basic auth and some example
users";
@ -82,23 +88,9 @@ cat <<EOF > $nacmfile
<read-default>deny</read-default>
<write-default>deny</write-default>
<exec-default>deny</exec-default>
<groups>
<group>
<name>admin</name>
<user-name>admin</user-name>
<user-name>adm1</user-name>
</group>
<group>
<name>limited</name>
<user-name>wilma</user-name>
<user-name>bam-bam</user-name>
</group>
<group>
<name>guest</name>
<user-name>guest</user-name>
<user-name>guest@example.com</user-name>
</group>
</groups>
$NGROUPS
<rule-list>
<name>guest-acl</name>
<group>guest</group>
@ -136,34 +128,27 @@ cat <<EOF > $nacmfile
</comment>
</rule>
</rule-list>
<rule-list>
<name>admin-acl</name>
<group>admin</group>
<rule>
<name>permit-all</name>
<module-name>*</module-name>
<access-operations>*</access-operations>
<action>permit</action>
<comment>
Allow the 'admin' group complete access to all operations and data.
</comment>
</rule>
</rule-list>
$NADMIN
</nacm>
EOF
# kill old backend (if any)
new "kill old backend -zf $cfg -y $fyang"
sudo clixon_backend -zf $cfg -y $fyang
if [ $? -ne 0 ]; then
err
fi
sleep 1
new "start backend -s init -f $cfg -y $fyang"
# start new backend
sudo $clixon_backend -s init -f $cfg -y $fyang
if [ $? -ne 0 ]; then
err
new "test params: -f $cfg -y $fyang"
if [ $BE -ne 0 ]; then
new "kill old backend -zf $cfg -y $fyang"
sudo clixon_backend -zf $cfg -y $fyang
if [ $? -ne 0 ]; then
err
fi
sleep 1
new "start backend -s init -f $cfg -y $fyang"
# start new backend
sudo $clixon_backend -s init -f $cfg -y $fyang -D $DBG
if [ $? -ne 0 ]; then
err
fi
fi
new "kill old restconf daemon"
@ -175,27 +160,27 @@ sudo su -c "$clixon_restconf -f $cfg -y $fyang -- -a" -s /bin/sh www-data &
sleep $RCWAIT
new "restconf DELETE whole datastore"
expecteq "$(curl -u adm1:bar -sS -X DELETE http://localhost/restconf/data)" ""
expecteq "$(curl -u andy:bar -sS -X DELETE http://localhost/restconf/data)" ""
new2 "auth get"
expecteq "$(curl -u adm1:bar -sS -X GET http://localhost/restconf/data/state)" '{"state": {"op": "42"}}
expecteq "$(curl -u andy:bar -sS -X GET http://localhost/restconf/data/state)" '{"state": {"op": "42"}}
'
new "Set x to 0"
expecteq "$(curl -u adm1:bar -sS -X PUT -d '{"x": 0}' http://localhost/restconf/data/x)" ""
expecteq "$(curl -u andy:bar -sS -X PUT -d '{"x": 0}' http://localhost/restconf/data/x)" ""
new2 "auth get (no user: access denied)"
expecteq "$(curl -sS -X GET -H \"Accept:\ application/yang-data+json\" http://localhost/restconf/data)" '{"ietf-restconf:errors" : {"error": {"error-tag": "access-denied","error-type": "protocol","error-severity": "error","error-message": "The requested URL was unauthorized"}}} '
new2 "auth get (wrong passwd: access denied)"
expecteq "$(curl -u adm1:foo -sS -X GET http://localhost/restconf/data)" '{"ietf-restconf:errors" : {"error": {"error-tag": "access-denied","error-type": "protocol","error-severity": "error","error-message": "The requested URL was unauthorized"}}} '
expecteq "$(curl -u andy:foo -sS -X GET http://localhost/restconf/data)" '{"ietf-restconf:errors" : {"error": {"error-tag": "access-denied","error-type": "protocol","error-severity": "error","error-message": "The requested URL was unauthorized"}}} '
new2 "auth get (access)"
expecteq "$(curl -u adm1:bar -sS -X GET http://localhost/restconf/data/x)" '{"x": 0}
expecteq "$(curl -u andy:bar -sS -X GET http://localhost/restconf/data/x)" '{"x": 0}
'
new2 "admin get nacm"
expecteq "$(curl -u adm1:bar -sS -X GET http://localhost/restconf/data/x)" '{"x": 0}
expecteq "$(curl -u andy:bar -sS -X GET http://localhost/restconf/data/x)" '{"x": 0}
'
new2 "limited get nacm"
@ -203,19 +188,19 @@ expecteq "$(curl -u wilma:bar -sS -X GET http://localhost/restconf/data/x)" '{"x
'
new2 "guest get nacm"
expecteq "$(curl -u guest:bar -sS -X GET http://localhost/restconf/data/x)" '{"ietf-restconf:errors" : {"error": {"error-tag": "access-denied","error-type": "protocol","error-severity": "error","error-message": "The requested URL was unauthorized"}}} '
expecteq "$(curl -u guest:bar -sS -X GET http://localhost/restconf/data/x)" '{"ietf-restconf:errors" : {"error": {"error-tag": "access-denied","error-type": "protocol","error-severity": "error","error-message": "access denied"}}} '
new "admin edit nacm"
expecteq "$(curl -u adm1:bar -sS -X PUT -d '{"x": 1}' http://localhost/restconf/data/x)" ""
expecteq "$(curl -u andy:bar -sS -X PUT -d '{"x": 1}' http://localhost/restconf/data/x)" ""
new2 "limited edit nacm"
expecteq "$(curl -u wilma:bar -sS -X PUT -d '{"x": 2}' http://localhost/restconf/data/x)" '{"ietf-restconf:errors" : {"error": {"error-tag": "access-denied","error-type": "protocol","error-severity": "error","error-message": "default deny"}}} '
new2 "guest edit nacm"
expecteq "$(curl -u guest:bar -sS -X PUT -d '{"x": 3}' http://localhost/restconf/data/x)" '{"ietf-restconf:errors" : {"error": {"error-tag": "access-denied","error-type": "protocol","error-severity": "error","error-message": "The requested URL was unauthorized"}}} '
expecteq "$(curl -u guest:bar -sS -X PUT -d '{"x": 3}' http://localhost/restconf/data/x)" '{"ietf-restconf:errors" : {"error": {"error-tag": "access-denied","error-type": "protocol","error-severity": "error","error-message": "access denied"}}} '
new "cli show conf as admin"
expectfn "$clixon_cli -1 -U adm1 -l o -f $cfg -y $fyang show conf" 0 "^x 1;$"
expectfn "$clixon_cli -1 -U andy -l o -f $cfg -y $fyang show conf" 0 "^x 1;$"
new "cli show conf as limited"
expectfn "$clixon_cli -1 -U wilma -l o -f $cfg -y $fyang show conf" 0 "^x 1;$"
@ -224,7 +209,7 @@ new "cli show conf as guest"
expectfn "$clixon_cli -1 -U guest -l o -f $cfg -y $fyang show conf" 255 "protocol access-denied"
new "cli rpc as admin"
expectfn "$clixon_cli -1 -U adm1 -l o -f $cfg -y $fyang rpc ipv4" 0 "<next-hop-list>2.3.4.5</next-hop-list>"
expectfn "$clixon_cli -1 -U andy -l o -f $cfg -y $fyang rpc ipv4" 0 "<next-hop-list>2.3.4.5</next-hop-list>"
new "cli rpc as limited"
expectfn "$clixon_cli -1 -U wilma -l o -f $cfg -y $fyang rpc ipv4" 255 "protocol access-denied default deny"
@ -235,6 +220,10 @@ expectfn "$clixon_cli -1 -U guest -l o -f $cfg -y $fyang rpc ipv4" 255 "protocol
new "Kill restconf daemon"
sudo pkill -u www-data -f "/www-data/clixon_restconf"
if [ $BE -ne 0 ]; then
exit # BE
fi
new "Kill backend"
# Check if premature kill
pid=`pgrep -u root -f clixon_backend`