Fixed a problem with some netconf error messages caused restconf daemon to exit due to no XML encoding

This commit is contained in:
Olof hagsand 2019-06-12 18:15:44 +02:00
parent de15b2bf80
commit 98cc62eace
7 changed files with 68 additions and 29 deletions

View file

@ -237,6 +237,7 @@
### Corrected Bugs
* Fixed a problem with some netconf error messages caused restconf daemon to exit due to no XML encoding
* Check cligen tab mode, dont start if CLICON_CLI_TAB_MODE is undefined
* Startup transactions did not mark added tree with XML_FLAG_ADD as it should.
* Restconf PUT different keys detected (thanks @dcornejo) and fixed

View file

@ -74,7 +74,7 @@
* The request requires a resource that already is in use.
* @param[out] cb CLIgen buf. Error XML is written in this buffer
* @param[in] type Error type: "application" or "protocol"
* @param[in] message Error message
* @param[in] message Error message (will be XML encoded)
*/
int
netconf_in_use(cbuf *cb,
@ -113,7 +113,7 @@ netconf_in_use(cbuf *cb,
* The request specifies an unacceptable value for one or more parameters.
* @param[out] cb CLIgen buf. Error XML is written in this buffer
* @param[in] type Error type: "application" or "protocol"
* @param[in] message Error message
* @param[in] message Error message (will be XML encoded)
*/
int
netconf_invalid_value(cbuf *cb,
@ -153,7 +153,7 @@ netconf_invalid_value(cbuf *cb,
* too large for the implementation to handle.
* @param[out] cb CLIgen buf. Error XML is written in this buffer
* @param[in] type Error type: "transport", "rpc", "application", "protocol"
* @param[in] message Error message
* @param[in] message Error message (will be XML encoded)
*/
int
netconf_too_big(cbuf *cb,
@ -193,7 +193,7 @@ netconf_too_big(cbuf *cb,
* @param[out] cb CLIgen buf. Error XML is written in this buffer
* @param[in] type Error type: "rpc", "application" or "protocol"
* @param[in] info bad-attribute or bad-element xml
* @param[in] message Error message
* @param[in] message Error message (will be XML encoded)
*/
int
netconf_missing_attribute(cbuf *cb,
@ -234,7 +234,7 @@ netconf_missing_attribute(cbuf *cb,
* @param[out] cb CLIgen buf. Error XML is written in this buffer
* @param[in] type Error type: "rpc", "application" or "protocol"
* @param[in] info bad-attribute or bad-element xml
* @param[in] message Error message
* @param[in] message Error message (will be XML encoded)
*/
int
netconf_bad_attribute(cbuf *cb,
@ -317,7 +317,7 @@ netconf_unknown_attribute(cbuf *cb,
* @param[in] type Error type: "application" or "protocol"
* @param[in] tag Error tag
* @param[in] element bad-element xml
* @param[in] message Error message
* @param[in] message Error message (will be XML encoded)
*/
static int
netconf_common_xml(cxobj **xret,
@ -327,8 +327,9 @@ netconf_common_xml(cxobj **xret,
char *element,
char *message)
{
int retval =-1;
int retval =-1;
cxobj *xerr;
char *encstr = NULL;
if (*xret == NULL){
if ((*xret = xml_new("rpc-reply", NULL, NULL)) == NULL)
@ -344,11 +345,17 @@ netconf_common_xml(cxobj **xret,
"<error-severity>error</error-severity>",
type, tag, infotag, element, infotag) < 0)
goto done;
if (message && xml_parse_va(&xerr, NULL, "<error-message>%s</error-message>",
message) < 0)
goto done;
if (message){
if (xml_chardata_encode(&encstr, "%s", message) < 0)
goto done;
if (xml_parse_va(&xerr, NULL, "<error-message>%s</error-message>",
encstr) < 0)
goto done;
}
retval = 0;
done:
if (encstr)
free(encstr);
return retval;
}
@ -555,7 +562,7 @@ netconf_access_denied(cbuf *cb,
* authorization failed.
* @param[out] xret Error XML tree. Free with xml_free after use
* @param[in] type Error type: "application" or "protocol"
* @param[in] message Error message
* @param[in] message Error message (will be XML encoded)
* @code
* cxobj *xret = NULL;
* if (netconf_access_denied_xml(&xret, "protocol", "Unauthorized") < 0)
@ -569,8 +576,9 @@ netconf_access_denied_xml(cxobj **xret,
char *type,
char *message)
{
int retval =-1;
int retval =-1;
cxobj *xerr;
char *encstr = NULL;
if (*xret == NULL){
if ((*xret = xml_new("rpc-reply", NULL, NULL)) == NULL)
@ -584,11 +592,17 @@ netconf_access_denied_xml(cxobj **xret,
"<error-tag>access-denied</error-tag>"
"<error-severity>error</error-severity>", type) < 0)
goto done;
if (message && xml_parse_va(&xerr, NULL, "<error-message>%s</error-message>",
message) < 0)
goto done;
if (message){
if (xml_chardata_encode(&encstr, "%s", message) < 0)
goto done;
if (xml_parse_va(&xerr, NULL, "<error-message>%s</error-message>",
encstr) < 0)
goto done;
}
retval = 0;
done:
if (encstr)
free(encstr);
return retval;
}
@ -905,7 +919,7 @@ netconf_operation_failed(cbuf *cb,
* some reason not covered by any other error condition.
* @param[out] xret Error XML tree
* @param[in] type Error type: "rpc", "application" or "protocol"
* @param[in] message Error message
* @param[in] message Error message (will be XML encoded)
* @code
* cxobj *xret = NULL;
* if (netconf_operation_failed_xml(&xret, "protocol", "Unauthorized") < 0)
@ -921,6 +935,7 @@ netconf_operation_failed_xml(cxobj **xret,
{
int retval =-1;
cxobj *xerr;
char *encstr = NULL;
if (*xret == NULL){
if ((*xret = xml_new("rpc-reply", NULL, NULL)) == NULL)
@ -934,11 +949,17 @@ netconf_operation_failed_xml(cxobj **xret,
"<error-tag>operation-failed</error-tag>"
"<error-severity>error</error-severity>", type) < 0)
goto done;
if (message && xml_parse_va(&xerr, NULL, "<error-message>%s</error-message>",
message) < 0)
if (message){
if (xml_chardata_encode(&encstr, "%s", message) < 0)
goto done;
if (xml_parse_va(&xerr, NULL, "<error-message>%s</error-message>",
encstr) < 0)
goto done;
}
retval = 0;
done:
if (encstr)
free(encstr);
return retval;
}
@ -976,7 +997,7 @@ netconf_malformed_message(cbuf *cb,
* For example, the message is not well-formed XML or it uses an
* invalid character set.
* @param[out] xret Error XML tree
* @param[in] message Error message
* @param[in] message Error message (will be XML encoded)
* @note New in :base:1.1
* @code
* cxobj *xret = NULL;
@ -990,8 +1011,9 @@ int
netconf_malformed_message_xml(cxobj **xret,
char *message)
{
int retval =-1;
int retval =-1;
cxobj *xerr;
char *encstr = NULL;
if (*xret == NULL){
if ((*xret = xml_new("rpc-reply", NULL, NULL)) == NULL)
@ -1005,11 +1027,17 @@ netconf_malformed_message_xml(cxobj **xret,
"<error-tag>malformed-message</error-tag>"
"<error-severity>error</error-severity>") < 0)
goto done;
if (message && xml_parse_va(&xerr, NULL, "<error-message>%s</error-message>",
message) < 0)
goto done;
if (message){
if (xml_chardata_encode(&encstr, "%s", message) < 0)
goto done;
if (xml_parse_va(&xerr, NULL, "<error-message>%s</error-message>",
encstr) < 0)
goto done;
}
retval = 0;
done:
if (encstr)
free(encstr);
return retval;
}

View file

@ -2212,7 +2212,9 @@ xml_spec_populate_rpc(clicon_handle h,
if (yrpc){
xml_spec_set(x, yrpc);
if ((yi = yang_find(yrpc, Y_INPUT, NULL)) != NULL){
/* kludge rpc -> input XXX THIS HIDES AN ERROR IN xml_spec_populate */
/* xml_spec_populate need to have parent with yang spec for
* recursive population to work. Therefore, assign input yang
* to rpc level although not 100% intuitive */
xml_spec_set(x, yi);
if (xml_apply(x, CX_ELMNT, xml_spec_populate, yspec) < 0)
goto done;

View file

@ -149,7 +149,8 @@ new "start restconf daemon (-a is enable http basic auth)"
start_restconf -f $cfg -- -a
new "waiting"
sleep $RCWAIT
wait_backend
wait_restconf
new "auth get"
expecteq "$(curl -u andy:bar -sS -X GET http://localhost/restconf/data)" 0 '{"data": {"clixon-example:state": {"op": ["42","41","43"]}}}

View file

@ -46,7 +46,7 @@ if [ $BE -ne 0 ]; then
start_backend -s init -f $cfg -- -s
new "waiting"
sleep $RCWAIT
wait_backend
fi
new "netconf hello"

View file

@ -90,6 +90,10 @@ wait_restconf
new "restconf PUT add whole list entry"
expectfn 'curl -s -X PUT http://localhost/restconf/data/list:c/a=x,y -d {"list:a":{"b":"x","c":"y","nonkey":"0"}}' 0 ''
new "restconf PUT add whole list entry XML"
expecteq "$(curl -s -X PUT -H 'Content-Type: application/yang-data+xml' -H 'Accept: application/yang-data+xml' -d '<a xmlns="urn:example:clixon"><b>xx</b><c>xy</c><nonkey>0</nonkey></a>' http://localhost/restconf/data/list:c/a=xx,xy)" 0 ''
new "restconf PUT change whole list entry (same keys)"
expectfn 'curl -s -X PUT http://localhost/restconf/data/list:c/a=x,y -d {"list:a":{"b":"x","c":"y","nonkey":"z"}}' 0 ''
@ -99,6 +103,9 @@ expectfn 'curl -s -X PUT http://localhost/restconf/data/list:c/a=x,y -d {"a":{"b
new "restconf PUT change list entry (wrong keys)(expect fail)"
expectfn 'curl -s -X PUT http://localhost/restconf/data/list:c/a=x,y -d {"list:a":{"b":"y","c":"x"}}' 0 '{"ietf-restconf:errors" : {"error": {"error-type": "protocol","error-tag": "operation-failed","error-severity": "error","error-message": "api-path keys do not match data keys"}}}'
new "restconf PUT change list entry (wrong keys)(expect fail) XML"
expecteq "$(curl -s -X PUT -H 'Content-Type: application/yang-data+xml' -H 'Accept: application/yang-data+xml' -d '<a xmlns="urn:example:clixon"><b>xy</b><c>xz</c><nonkey>0</nonkey></a>' http://localhost/restconf/data/list:c/a=xx,xy)" 0 '<errors xmlns="urn:ietf:params:xml:ns:yang:ietf-restconf"><error><error-type>protocol</error-type><error-tag>operation-failed</error-tag><error-severity>error</error-severity><error-message>api-path keys do not match data keys</error-message></error></errors> '
new "restconf PUT change list entry (just one key)(expect fail)"
expectfn 'curl -s -X PUT http://localhost/restconf/data/list:c/a=x -d {"list:a":{"b":"x"}}' 0 '{"ietf-restconf:errors" : {"error": {"error-type": "rpc","error-tag": "malformed-message","error-severity": "error","error-message": "List key a length mismatch"}}} '

View file

@ -77,11 +77,11 @@ expecteq "$(curl -s -X POST -d '{"clixon-example:input":{"x":"0","y":"99"}}' htt
new "restconf example rpc json/json"
# XXX example:input example:output
expecteq "$(curl -s -X POST -H 'Content-Type: application/yang-data+json' -H 'Content-Type: application/yang-data+json' -d '{"clixon-example:input":{"x":"0"}}' http://localhost/restconf/operations/clixon-example:example)" 0 '{"clixon-example:output": {"x": "0","y": "42"}}
expecteq "$(curl -s -X POST -H 'Content-Type: application/yang-data+json' -H 'Accept: application/yang-data+json' -d '{"clixon-example:input":{"x":"0"}}' http://localhost/restconf/operations/clixon-example:example)" 0 '{"clixon-example:output": {"x": "0","y": "42"}}
'
new "restconf example rpc xml/json"
expecteq "$(curl -s -X POST -H 'Content-Type: application/yang-data+xml' -H 'Content-Type: application/yang-data+json' -d '<input xmlns="urn:example:clixon"><x>0</x></input>' http://localhost/restconf/operations/clixon-example:example)" 0 '{"clixon-example:output": {"x": "0","y": "42"}}
expecteq "$(curl -s -X POST -H 'Content-Type: application/yang-data+xml' -H 'Accept: application/yang-data+json' -d '<input xmlns="urn:example:clixon"><x>0</x></input>' http://localhost/restconf/operations/clixon-example:example)" 0 '{"clixon-example:output": {"x": "0","y": "42"}}
'
new "restconf example rpc json/xml"