* RPC replies now verified with YANG

* Stricter checking of outgoing RPC replies from server
  * See [RPC output not verified by yang](https://github.com/clicon/clixon/issues/283)
  * This lead to some corrections of RPC replies in system code
This commit is contained in:
Olof hagsand 2021-11-16 22:09:16 +01:00
parent cfe1f2936e
commit 0626de9431
11 changed files with 197 additions and 26 deletions

View file

@ -217,14 +217,15 @@ clixon_stats_get_db(clicon_handle h,
xt = xmldb_cache_get(h, dbname);
}
if (xt == NULL){
cprintf(cb, "<datastore><name>%s</name><nr>0</nr><size>0</size></datastore>", dbname);
cprintf(cb, "<datastore xmlns=\"%s\"><name>%s</name><nr>0</nr><size>0</size></datastore>",
CLIXON_LIB_NS, dbname);
}
else{
if (xml_stats(xt, &nr, &sz) < 0)
goto done;
cprintf(cb, "<datastore><name>%s</name><nr>%" PRIu64 "</nr>"
cprintf(cb, "<datastore xmlns=\"%s\"><name>%s</name><nr>%" PRIu64 "</nr>"
"<size>%zu</size></datastore>",
dbname, nr, sz);
CLIXON_LIB_NS, dbname, nr, sz);
}
retval = 0;
done:
@ -1001,7 +1002,7 @@ from_client_stats(clicon_handle h,
cprintf(cbret, "<rpc-reply xmlns=\"%s\">", NETCONF_BASE_NAMESPACE);
nr=0;
xml_stats_global(&nr);
cprintf(cbret, "<global><xmlnr>%" PRIu64 "</xmlnr></global>", nr);
cprintf(cbret, "<global xmlns=\"%s\"><xmlnr>%" PRIu64 "</xmlnr></global>", CLIXON_LIB_NS, nr);
if (clixon_stats_get_db(h, "running", cbret) < 0)
goto done;
if (clixon_stats_get_db(h, "candidate", cbret) < 0)
@ -1136,6 +1137,7 @@ from_client_hello(clicon_handle h,
return retval;
}
/*! An internal clicon message has arrived from a client. Receive and dispatch.
* @param[in] h Clicon handle
* @param[in] s Socket where message arrived. read from this.
@ -1168,6 +1170,7 @@ from_client_msg(clicon_handle h,
char *rpcname;
char *rpcprefix;
char *namespace = NULL;
int nr = 0;
clicon_debug(1, "%s", __FUNCTION__);
yspec = clicon_dbspec_yang(h);
@ -1295,13 +1298,15 @@ from_client_msg(clicon_handle h,
goto reply;
}
clicon_err_reset();
if ((ret = rpc_callback_call(h, xe, cbret, ce)) < 0){
if ((ret = rpc_callback_call(h, xe, ce, &nr, cbret)) < 0){
if (netconf_operation_failed(cbret, "application", clicon_err_reason)< 0)
goto done;
clicon_log(LOG_NOTICE, "%s Error in rpc_callback_call:%s", __FUNCTION__, xml_name(xe));
goto reply; /* Dont quit here on user callbacks */
}
if (ret == 0){ /* not handled by callback */
if (ret == 0)
goto reply;
if (nr == 0){ /* not handled by callback */
if (netconf_operation_not_supported(cbret, "application", "RPC operation not supported")< 0)
goto done;
goto reply;

View file

@ -588,6 +588,7 @@ netconf_application_rpc(clicon_handle h,
cbuf *cb = NULL;
cbuf *cbret = NULL;
int ret;
int nr = 0;
/* First check system / netconf RPC:s */
if ((cb = cbuf_new()) == NULL){
@ -623,9 +624,13 @@ netconf_application_rpc(clicon_handle h,
if (yrpc != NULL){
/* No need to check xn arguments with input statement since already bound and validated. */
/* Look for local (client-side) netconf plugins. */
if ((ret = rpc_callback_call(h, xn, cbret, NULL)) < 0)
if ((ret = rpc_callback_call(h, xn, NULL, &nr, cbret)) < 0)
goto done;
if (ret > 0){ /* Handled locally */
if (ret == 0){
if (clixon_xml_parse_string(cbuf_get(cbret), YB_NONE, NULL, xret, NULL) < 0)
goto done;
}
else if (nr > 0){ /* Handled locally */
if (clixon_xml_parse_string(cbuf_get(cbret), YB_NONE, NULL, xret, NULL) < 0)
goto done;
}

View file

@ -712,6 +712,7 @@ api_operations_post(clicon_handle h,
char *id = NULL;
yang_stmt *ys = NULL;
char *namespace = NULL;
int nr = 0;
clicon_debug(1, "%s json:\"%s\" path:\"%s\"", __FUNCTION__, data, api_path);
/* 1. Initialize */
@ -826,9 +827,16 @@ api_operations_post(clicon_handle h,
/* Look for local (client-side) restconf plugins.
* -1:Error, 0:OK local, 1:OK backend
*/
if ((ret = rpc_callback_call(h, xbot, cbret, req)) < 0)
if ((ret = rpc_callback_call(h, xbot, req, &nr, cbret)) < 0)
goto done;
if (ret > 0){ /* Handled locally */
if (ret == 0){
if (clixon_xml_parse_string(cbuf_get(cbret), YB_NONE, NULL, &xe, NULL) < 0)
goto done;
if (api_return_err(h, req, xe, pretty, media_out, 0) < 0)
goto done;
goto ok;
}
else if (nr > 0){ /* Handled locally */
if (clixon_xml_parse_string(cbuf_get(cbret), YB_NONE, NULL, &xret, NULL) < 0)
goto done;
/* Local error: return it and quit */