* Restconf authentication callback (ca_auth) signature changed
* Not backward compatible: All uses of the ca-auth callback in restconf plugins must be changed
* New version is: `int ca_auth(h, req, auth_type, authp, userp)`
* where `auth_type` is the requested authentication-type (none, client-cert or user-defined)
* `authp` is the returned authentication flag
* `userp` is the returned associated authenticated user
* and the return value is three-valued: -1: Error, 0: ignored, 1: OK
* For more info see [clixon-docs](https://clixon-docs.readthedocs.io/en/latest/restconf.html)
* New clixon-restconf@2020-12-30.yang revision
This commit is contained in:
parent
1f0147f996
commit
710fc76887
54 changed files with 1216 additions and 485 deletions
|
|
@ -75,6 +75,7 @@
|
|||
#include "backend_commit.h"
|
||||
#include "backend_handle.h"
|
||||
#include "backend_startup.h"
|
||||
#include "backend_plugin_restconf.h"
|
||||
|
||||
/* Command line options to be passed to getopt(3) */
|
||||
#define BACKEND_OPTS "hD:f:E:l:d:p:b:Fza:u:P:1qs:c:U:g:y:o:"
|
||||
|
|
@ -388,169 +389,6 @@ ret2status(int ret,
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------
|
||||
* Restconf process pseudo plugin
|
||||
*/
|
||||
|
||||
#define RESTCONF_PROCESS "restconf"
|
||||
|
||||
/*! Process rpc callback function
|
||||
* - if RPC op is start, if enable is true, start the service, if false, error or ignore it
|
||||
* - if RPC op is stop, stop the service
|
||||
* These rules give that if RPC op is start and enable is false -> change op to none
|
||||
*/
|
||||
int
|
||||
restconf_rpc_wrapper(clicon_handle h,
|
||||
process_entry_t *pe,
|
||||
char **operation)
|
||||
{
|
||||
int retval = -1;
|
||||
cxobj *xt = NULL;
|
||||
|
||||
clicon_debug(1, "%s", __FUNCTION__);
|
||||
if (strcmp(*operation, "stop") == 0){
|
||||
/* if RPC op is stop, stop the service */
|
||||
}
|
||||
else if (strcmp(*operation, "start") == 0){
|
||||
/* RPC op is start & enable is true, then start the service,
|
||||
& enable is false, error or ignore it */
|
||||
if (xmldb_get(h, "running", NULL, "/restconf", &xt) < 0)
|
||||
goto done;
|
||||
if (xt != NULL &&
|
||||
xpath_first(xt, NULL, "/restconf[enable='false']") != NULL) {
|
||||
*operation = "none";
|
||||
}
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
if (xt)
|
||||
xml_free(xt);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Enable process-control of restconf daemon, ie start/stop restconf by registering restconf process
|
||||
* @param[in] h Clicon handle
|
||||
* @note Could also look in clixon-restconf and start process if enable is true, but that needs to
|
||||
* be in start callback using a pseudo plugin.
|
||||
*/
|
||||
static int
|
||||
restconf_pseudo_process_control(clicon_handle h)
|
||||
{
|
||||
int retval = -1;
|
||||
char **argv = NULL;
|
||||
int i;
|
||||
int nr;
|
||||
char dbgstr[8];
|
||||
char wwwstr[64];
|
||||
|
||||
nr = 4;
|
||||
if (clicon_debug_get() != 0)
|
||||
nr += 2;
|
||||
if ((argv = calloc(nr, sizeof(char *))) == NULL){
|
||||
clicon_err(OE_UNIX, errno, "calloc");
|
||||
goto done;
|
||||
}
|
||||
i = 0;
|
||||
snprintf(wwwstr, sizeof(wwwstr)-1, "%s/clixon_restconf", clicon_option_str(h, "CLICON_WWWDIR"));
|
||||
argv[i++] = wwwstr;
|
||||
argv[i++] = "-f";
|
||||
argv[i++] = clicon_option_str(h, "CLICON_CONFIGFILE");
|
||||
if (clicon_debug_get() != 0){
|
||||
argv[i++] = "-D";
|
||||
snprintf(dbgstr, sizeof(dbgstr)-1, "%d", clicon_debug_get());
|
||||
argv[i++] = dbgstr;
|
||||
}
|
||||
argv[i++] = NULL;
|
||||
assert(i==nr);
|
||||
if (clixon_process_register(h, RESTCONF_PROCESS,
|
||||
NULL /* XXX network namespace */,
|
||||
restconf_rpc_wrapper,
|
||||
argv, nr) < 0)
|
||||
goto done;
|
||||
if (argv != NULL)
|
||||
free(argv);
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Restconf pseduo-plugin process validate
|
||||
*/
|
||||
static int
|
||||
restconf_pseudo_process_validate(clicon_handle h,
|
||||
transaction_data td)
|
||||
{
|
||||
int retval = -1;
|
||||
cxobj *xtarget;
|
||||
|
||||
clicon_debug(1, "%s", __FUNCTION__);
|
||||
xtarget = transaction_target(td);
|
||||
/* If ssl-enable is true and (at least a) socket has ssl,
|
||||
* then server-cert-path and server-key-path must exist */
|
||||
if (xpath_first(xtarget, NULL, "restconf/enable[.='true']") &&
|
||||
xpath_first(xtarget, NULL, "restconf/socket[ssl='true']")){
|
||||
/* Should filepath be checked? One could claim this is a runtime system,... */
|
||||
if (xpath_first(xtarget, 0, "restconf/server-cert-path") == NULL){
|
||||
clicon_err(OE_CFG, 0, "SSL enabled but server-cert-path not set");
|
||||
return -1; /* induce fail */
|
||||
}
|
||||
if (xpath_first(xtarget, 0, "restconf/server-key-path") == NULL){
|
||||
clicon_err(OE_CFG, 0, "SSL enabled but server-key-path not set");
|
||||
return -1; /* induce fail */
|
||||
}
|
||||
}
|
||||
retval = 0;
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Restconf pseduo-plugin process commit
|
||||
*/
|
||||
static int
|
||||
restconf_pseudo_process_commit(clicon_handle h,
|
||||
transaction_data td)
|
||||
{
|
||||
int retval = -1;
|
||||
cxobj *xtarget;
|
||||
cxobj *cx;
|
||||
int enabled = 0;
|
||||
|
||||
clicon_debug(1, "%s", __FUNCTION__);
|
||||
xtarget = transaction_target(td);
|
||||
if (xpath_first(xtarget, NULL, "/restconf[enable='true']") != NULL)
|
||||
enabled++;
|
||||
if ((cx = xpath_first(xtarget, NULL, "/restconf/enable")) != NULL &&
|
||||
xml_flag(cx, XML_FLAG_CHANGE|XML_FLAG_ADD)){
|
||||
if (clixon_process_operation(h, RESTCONF_PROCESS,
|
||||
enabled?"start":"stop", 0, NULL) < 0)
|
||||
goto done;
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Register start/stop restconf RPC and create pseudo-plugin to monitor enable flag
|
||||
* @param[in] h Clixon handle
|
||||
*/
|
||||
static int
|
||||
restconf_pseudo_process_reg(clicon_handle h,
|
||||
yang_stmt *yspec)
|
||||
{
|
||||
int retval = -1;
|
||||
clixon_plugin *cp = NULL;
|
||||
|
||||
if (clixon_pseudo_plugin(h, "restconf pseudo plugin", &cp) < 0)
|
||||
goto done;
|
||||
cp->cp_api.ca_trans_commit = restconf_pseudo_process_commit;
|
||||
cp->cp_api.ca_trans_validate = restconf_pseudo_process_validate;
|
||||
|
||||
/* Register generic process-control of restconf daemon, ie start/stop restconf */
|
||||
if (restconf_pseudo_process_control(h) < 0)
|
||||
goto done;
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Debug timer */
|
||||
int
|
||||
|
|
@ -981,7 +819,7 @@ main(int argc,
|
|||
goto done;
|
||||
/* Check restconf start/stop from backend */
|
||||
if (clicon_option_bool(h, "CLICON_BACKEND_RESTCONF_PROCESS")){
|
||||
if (restconf_pseudo_process_reg(h, yspec) < 0)
|
||||
if (backend_plugin_restconf_register(h, yspec) < 0)
|
||||
goto done;
|
||||
}
|
||||
/* Here all modules are loaded
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue