* plugin_start() callbacks added for restconf
* Hard-wired users for authentication example
This commit is contained in:
parent
602f5034b4
commit
d57a6cf53c
8 changed files with 92 additions and 126 deletions
|
|
@ -71,6 +71,7 @@ clixon_plugin_api *clixon_plugin_init(clicon_handle h)
|
||||||
|
|
||||||
### Minor changes:
|
### Minor changes:
|
||||||
|
|
||||||
|
* plugin_start() callbacks added for restconf
|
||||||
* Authentication
|
* Authentication
|
||||||
* Example extended with http basic authentication for restconf
|
* Example extended with http basic authentication for restconf
|
||||||
* Documentation in FAQ.md
|
* Documentation in FAQ.md
|
||||||
|
|
|
||||||
|
|
@ -503,6 +503,7 @@ main(int argc,
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
int sock;
|
int sock;
|
||||||
|
char *argv0 = argv[0];
|
||||||
FCGX_Request request;
|
FCGX_Request request;
|
||||||
FCGX_Request *r = &request;
|
FCGX_Request *r = &request;
|
||||||
char c;
|
char c;
|
||||||
|
|
@ -511,6 +512,7 @@ main(int argc,
|
||||||
clicon_handle h;
|
clicon_handle h;
|
||||||
char *yangspec=NULL;
|
char *yangspec=NULL;
|
||||||
char *dir;
|
char *dir;
|
||||||
|
char *tmp;
|
||||||
|
|
||||||
/* In the startup, logs to stderr & debug flag set later */
|
/* In the startup, logs to stderr & debug flag set later */
|
||||||
clicon_log_init(__PROGRAM__, LOG_INFO, CLICON_LOG_SYSLOG);
|
clicon_log_init(__PROGRAM__, LOG_INFO, CLICON_LOG_SYSLOG);
|
||||||
|
|
@ -575,6 +577,14 @@ main(int argc,
|
||||||
if (yang_spec_main(h) == NULL)
|
if (yang_spec_main(h) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
/* Call start function in all plugins before we go interactive
|
||||||
|
Pass all args after the standard options to plugin_start
|
||||||
|
*/
|
||||||
|
tmp = *(argv-1);
|
||||||
|
*(argv-1) = argv0;
|
||||||
|
clixon_plugin_start(h, argc+1, argv-1);
|
||||||
|
*(argv-1) = tmp;
|
||||||
|
|
||||||
if ((sockpath = clicon_option_str(h, "CLICON_RESTCONF_PATH")) == NULL){
|
if ((sockpath = clicon_option_str(h, "CLICON_RESTCONF_PATH")) == NULL){
|
||||||
clicon_err(OE_CFG, errno, "No CLICON_RESTCONF_PATH in clixon configure file");
|
clicon_err(OE_CFG, errno, "No CLICON_RESTCONF_PATH in clixon configure file");
|
||||||
goto done;
|
goto done;
|
||||||
|
|
|
||||||
|
|
@ -11,27 +11,6 @@ module example {
|
||||||
}
|
}
|
||||||
description
|
description
|
||||||
"Example code that includes ietf-ip and ietf-routing";
|
"Example code that includes ietf-ip and ietf-routing";
|
||||||
container authentication {
|
|
||||||
description "Example code for enabling www basic auth and some example
|
|
||||||
users";
|
|
||||||
leaf basic_auth{
|
|
||||||
description "Basic user / password authentication as in HTTP basic auth";
|
|
||||||
type boolean;
|
|
||||||
default false;
|
|
||||||
}
|
|
||||||
list auth {
|
|
||||||
description "user / password entries. Valid if basic_auth=true";
|
|
||||||
key user;
|
|
||||||
leaf user{
|
|
||||||
description "User name";
|
|
||||||
type string;
|
|
||||||
}
|
|
||||||
leaf password{
|
|
||||||
description "Password";
|
|
||||||
type string;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rpc client-rpc {
|
rpc client-rpc {
|
||||||
description "Example local client-side RPC that is processed by the
|
description "Example local client-side RPC that is processed by the
|
||||||
the netconf/restconf and not sent to the backend.
|
the netconf/restconf and not sent to the backend.
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,11 @@ static const char Base64[] =
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||||
static const char Pad64 = '=';
|
static const char Pad64 = '=';
|
||||||
|
|
||||||
|
/* Use http basic auth. Set by starting restonf with:
|
||||||
|
clixon_restconf ... -- -a
|
||||||
|
*/
|
||||||
|
static int basic_auth = 0;
|
||||||
|
|
||||||
/* skips all whitespace anywhere.
|
/* skips all whitespace anywhere.
|
||||||
converts characters, four at a time, starting at (or after)
|
converts characters, four at a time, starting at (or after)
|
||||||
src from base - 64 numbers into three 8 bit bytes in the target area.
|
src from base - 64 numbers into three 8 bit bytes in the target area.
|
||||||
|
|
@ -181,22 +186,21 @@ b64_decode(const char *src,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Process a rest request that requires (cookie) "authentication"
|
/*! Process a rest request that requires (cookie) "authentication"
|
||||||
* Note, this is loaded as dlsym fixed symbol in plugin
|
|
||||||
* @param[in] h Clixon handle
|
* @param[in] h Clixon handle
|
||||||
* @param[in] arg Argument. Here: Fastcgi request handle
|
* @param[in] arg Argument. Here: Fastcgi request handle
|
||||||
* @retval -1 Fatal error
|
* @retval -1 Fatal error
|
||||||
* @retval 0 Unauth
|
* @retval 0 Unauth
|
||||||
* @retval 1 Auth
|
* @retval 1 Auth
|
||||||
*
|
* @note: Three hardwired users: adm1, wilma, guest w password "bar".
|
||||||
|
* Enabled by passing -- -a to the main function
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
plugin_credentials(clicon_handle h,
|
example_restconf_credentials(clicon_handle h,
|
||||||
void *arg)
|
void *arg)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
FCGX_Request *r = (FCGX_Request *)arg;
|
FCGX_Request *r = (FCGX_Request *)arg;
|
||||||
cxobj *xt = NULL;
|
cxobj *xt = NULL;
|
||||||
cxobj *x;
|
|
||||||
char *auth;
|
char *auth;
|
||||||
char *user = NULL;
|
char *user = NULL;
|
||||||
char *passwd;
|
char *passwd;
|
||||||
|
|
@ -204,22 +208,9 @@ plugin_credentials(clicon_handle h,
|
||||||
size_t authlen;
|
size_t authlen;
|
||||||
cbuf *cb = NULL;
|
cbuf *cb = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
char *xbody;
|
|
||||||
|
|
||||||
clicon_debug(1, "%s", __FUNCTION__);
|
/* HTTP basic authentication not enabled, pass with user "none" */
|
||||||
/* XXX This is a kludge to reset the user not remaining from previous */
|
if (basic_auth==0)
|
||||||
if (clicon_username_set(h, "admin") < 0)
|
|
||||||
goto done;
|
|
||||||
/* Check if basic_auth set, if not return OK */
|
|
||||||
if (clicon_rpc_get_config(h, "running", "authentication", &xt) < 0)
|
|
||||||
goto done;
|
|
||||||
if (clicon_username_set(h, "none") < 0)
|
|
||||||
goto done;
|
|
||||||
if ((x = xpath_first(xt, "authentication/basic_auth")) == NULL)
|
|
||||||
goto ok;
|
|
||||||
if ((xbody = xml_body(x)) == NULL)
|
|
||||||
goto ok;
|
|
||||||
if (strcmp(xbody, "true"))
|
|
||||||
goto ok;
|
goto ok;
|
||||||
/* At this point in the code we must use HTTP basic authentication */
|
/* At this point in the code we must use HTTP basic authentication */
|
||||||
if ((auth = FCGX_GetParam("HTTP_AUTHORIZATION", r->envp)) == NULL)
|
if ((auth = FCGX_GetParam("HTTP_AUTHORIZATION", r->envp)) == NULL)
|
||||||
|
|
@ -242,14 +233,15 @@ plugin_credentials(clicon_handle h,
|
||||||
goto fail;
|
goto fail;
|
||||||
*passwd = '\0';
|
*passwd = '\0';
|
||||||
passwd++;
|
passwd++;
|
||||||
clicon_debug(1, "%s user:%s passwd:%s", __FUNCTION__, user, passwd);
|
clicon_debug(1, "%s http user:%s passwd:%s", __FUNCTION__, user, passwd);
|
||||||
/* Here get auth sub-tree whjere all the users are */
|
/* Here get auth sub-tree whjere all the users are */
|
||||||
if ((cb = cbuf_new()) == NULL)
|
if ((cb = cbuf_new()) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
cprintf(cb, "authentication/auth[user=%s]", user);
|
/* Hardcoded user/passwd */
|
||||||
if ((x = xpath_first(xt, cbuf_get(cb))) == NULL)
|
if (strcmp(user, "wilma")==0 || strcmp(user, "adm1")==0 ||
|
||||||
goto fail;
|
strcmp(user, "quest")==0){
|
||||||
passwd2 = xml_find_body(x, "password");
|
passwd2 = "bar";
|
||||||
|
}
|
||||||
if (strcmp(passwd, passwd2))
|
if (strcmp(passwd, passwd2))
|
||||||
goto fail;
|
goto fail;
|
||||||
retval = 1;
|
retval = 1;
|
||||||
|
|
@ -287,14 +279,41 @@ restconf_client_rpc(clicon_handle h,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! Start example restonf plugin. Set authentication method
|
||||||
|
* Arguments are argc/argv after --
|
||||||
|
* Currently defined: -a enable http basic authentication
|
||||||
|
* Note hardwired users adm1, wilma and guest
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
example_restconf_start(clicon_handle h,
|
||||||
|
int argc,
|
||||||
|
char **argv)
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
|
||||||
|
clicon_debug(1, "%s argc:%d", __FUNCTION__, argc);
|
||||||
|
optind = 1;
|
||||||
|
opterr = 0;
|
||||||
|
while ((c = getopt(argc, argv, "a")) != -1){
|
||||||
|
switch (c) {
|
||||||
|
case 'a':
|
||||||
|
basic_auth = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
clixon_plugin_api * clixon_plugin_init(clicon_handle h);
|
clixon_plugin_api * clixon_plugin_init(clicon_handle h);
|
||||||
|
|
||||||
static clixon_plugin_api api = {
|
static clixon_plugin_api api = {
|
||||||
"example", /* name */
|
"example", /* name */
|
||||||
clixon_plugin_init, /* init */
|
clixon_plugin_init, /* init */
|
||||||
NULL, /* start */
|
example_restconf_start,/* start */
|
||||||
NULL, /* exit */
|
NULL, /* exit */
|
||||||
.ca_auth=plugin_credentials /* auth */
|
.ca_auth=example_restconf_credentials /* auth */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*! Restconf plugin initialization
|
/*! Restconf plugin initialization
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,9 @@ typedef int (*clicon_rpc_cb)(
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Called when backend started with cmd-line arguments from daemon call.
|
/* Called when backend started with cmd-line arguments from daemon call.
|
||||||
* @see plgstart_t
|
* Call plugin start functions with argc/argv multiple arguments.
|
||||||
|
* Typically the argc/argv are the ones appearing after "--", eg
|
||||||
|
* clicon_cli -f /etc/clicon.xml -- -a myopt
|
||||||
*/
|
*/
|
||||||
typedef int (plgstart_t)(clicon_handle, int, char **); /* Plugin start */
|
typedef int (plgstart_t)(clicon_handle, int, char **); /* Plugin start */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -288,6 +288,16 @@ done:
|
||||||
|
|
||||||
/*! Call plugin_start in all plugins
|
/*! Call plugin_start in all plugins
|
||||||
* @param[in] h Clicon handle
|
* @param[in] h Clicon handle
|
||||||
|
* @param[in] argc
|
||||||
|
* @param[in] argv
|
||||||
|
* Call plugin start functions (if defined) with argc/argv multiple
|
||||||
|
* arguments.
|
||||||
|
* Typically the argc/argv are the ones appearing after "--", eg
|
||||||
|
* clicon_cli -f /etc/clicon.xml -- -a myopt
|
||||||
|
* In the example above argc=3 and
|
||||||
|
* argv[0]: clicon_cli
|
||||||
|
* argv[1]: -a
|
||||||
|
* argv[2]: myopt
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
clixon_plugin_start(clicon_handle h,
|
clixon_plugin_start(clicon_handle h,
|
||||||
|
|
@ -369,7 +379,7 @@ clixon_plugin_auth(clicon_handle h,
|
||||||
if ((authfn = cp->cp_api.ca_auth) == NULL)
|
if ((authfn = cp->cp_api.ca_auth) == NULL)
|
||||||
continue;
|
continue;
|
||||||
if ((retval = authfn(h, arg)) < 0) {
|
if ((retval = authfn(h, arg)) < 0) {
|
||||||
clicon_debug(1, "plugin_start() failed\n");
|
clicon_debug(1, "plugin_auth() failed\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -36,27 +36,6 @@ module $APPNAME{
|
||||||
import ietf-netconf-acm {
|
import ietf-netconf-acm {
|
||||||
prefix nacm;
|
prefix nacm;
|
||||||
}
|
}
|
||||||
container authentication {
|
|
||||||
description "Example code for enabling www basic auth and some example
|
|
||||||
users";
|
|
||||||
leaf basic_auth{
|
|
||||||
description "Basic user / password authentication as in HTTP basic auth";
|
|
||||||
type boolean;
|
|
||||||
default false;
|
|
||||||
}
|
|
||||||
list auth {
|
|
||||||
description "user / password entries. Valid if basic_auth=true";
|
|
||||||
key user;
|
|
||||||
leaf user{
|
|
||||||
description "User name";
|
|
||||||
type string;
|
|
||||||
}
|
|
||||||
leaf password{
|
|
||||||
description "Password";
|
|
||||||
type string;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
leaf x{
|
leaf x{
|
||||||
type int32;
|
type int32;
|
||||||
description "something to edit";
|
description "something to edit";
|
||||||
|
|
@ -65,18 +44,6 @@ module $APPNAME{
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
RULES=$(cat <<EOF
|
RULES=$(cat <<EOF
|
||||||
<authentication>
|
|
||||||
<basic_auth>true</basic_auth>
|
|
||||||
<auth>
|
|
||||||
<user>adm1</user><password>bar</password>
|
|
||||||
</auth>
|
|
||||||
<auth>
|
|
||||||
<user>wilma</user><password>bar</password>
|
|
||||||
</auth>
|
|
||||||
<auth>
|
|
||||||
<user>guest</user><password>bar</password>
|
|
||||||
</auth>
|
|
||||||
</authentication>
|
|
||||||
<nacm>
|
<nacm>
|
||||||
<enable-nacm>false</enable-nacm>
|
<enable-nacm>false</enable-nacm>
|
||||||
<read-default>deny</read-default>
|
<read-default>deny</read-default>
|
||||||
|
|
@ -172,8 +139,8 @@ fi
|
||||||
new "kill old restconf daemon"
|
new "kill old restconf daemon"
|
||||||
sudo pkill -u www-data clixon_restconf
|
sudo pkill -u www-data clixon_restconf
|
||||||
sleep 1
|
sleep 1
|
||||||
new "start restconf daemon"
|
new "start restconf daemon (-a is enable basic authentication)"
|
||||||
sudo start-stop-daemon -S -q -o -b -x /www-data/clixon_restconf -d /www-data -c www-data -- -f $cfg -y $fyang
|
sudo start-stop-daemon -S -q -o -b -x /www-data/clixon_restconf -d /www-data -c www-data -- -f $cfg -y $fyang -- -a
|
||||||
|
|
||||||
sleep 1
|
sleep 1
|
||||||
|
|
||||||
|
|
@ -214,7 +181,7 @@ expecteq "$(curl -u wilma:bar -sS -X GET http://localhost/restconf/data/x)" '{"x
|
||||||
'
|
'
|
||||||
|
|
||||||
new2 "guest get nacm"
|
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": "access denied"}}}
'
|
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"}}}
'
|
||||||
|
|
||||||
new "admin edit nacm"
|
new "admin edit nacm"
|
||||||
expecteq "$(curl -u adm1:bar -sS -X PUT -d '{"x": 1}' http://localhost/restconf/data/x)" ""
|
expecteq "$(curl -u adm1:bar -sS -X PUT -d '{"x": 1}' http://localhost/restconf/data/x)" ""
|
||||||
|
|
@ -223,7 +190,7 @@ 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"}}}
'
|
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"
|
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": "access denied"}}}
'
|
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"}}}
'
|
||||||
|
|
||||||
new "Kill restconf daemon"
|
new "Kill restconf daemon"
|
||||||
sudo pkill -u www-data clixon_restconf
|
sudo pkill -u www-data clixon_restconf
|
||||||
|
|
|
||||||
52
test/test_auth_ext.sh
Normal file → Executable file
52
test/test_auth_ext.sh
Normal file → Executable file
|
|
@ -1,5 +1,6 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# Authentication and authorization and IETF NACM
|
# Authentication and authorization and IETF NACM
|
||||||
|
# External NACM file
|
||||||
# See RFC 8321 A.2
|
# See RFC 8321 A.2
|
||||||
# But replaced ietf-netconf-monitoring with *
|
# But replaced ietf-netconf-monitoring with *
|
||||||
|
|
||||||
|
|
@ -10,12 +11,13 @@ APPNAME=example
|
||||||
cfg=$dir/conf_yang.xml
|
cfg=$dir/conf_yang.xml
|
||||||
fyang=$dir/test.yang
|
fyang=$dir/test.yang
|
||||||
fyangerr=$dir/err.yang
|
fyangerr=$dir/err.yang
|
||||||
|
nacmfile=$dir/nacmfile
|
||||||
|
|
||||||
cat <<EOF > $cfg
|
cat <<EOF > $cfg
|
||||||
<config>
|
<config>
|
||||||
<CLICON_CONFIGFILE>$cfg</CLICON_CONFIGFILE>
|
<CLICON_CONFIGFILE>$cfg</CLICON_CONFIGFILE>
|
||||||
<CLICON_YANG_DIR>/usr/local/share/$APPNAME/yang</CLICON_YANG_DIR>
|
<CLICON_YANG_DIR>/usr/local/share/$APPNAME/yang</CLICON_YANG_DIR>
|
||||||
<CLICON_YANG_MODULE_MAIN>$APPNAME</CLICON_YANG_MODULE_MAIN>
|
<CLICON_YANG_MODULE_MAIN>$fyang</CLICON_YANG_MODULE_MAIN>
|
||||||
<CLICON_CLISPEC_DIR>/usr/local/lib/$APPNAME/clispec</CLICON_CLISPEC_DIR>
|
<CLICON_CLISPEC_DIR>/usr/local/lib/$APPNAME/clispec</CLICON_CLISPEC_DIR>
|
||||||
<CLICON_RESTCONF_DIR>/usr/local/lib/$APPNAME/restconf</CLICON_RESTCONF_DIR>
|
<CLICON_RESTCONF_DIR>/usr/local/lib/$APPNAME/restconf</CLICON_RESTCONF_DIR>
|
||||||
<CLICON_CLI_DIR>/usr/local/lib/$APPNAME/cli</CLICON_CLI_DIR>
|
<CLICON_CLI_DIR>/usr/local/lib/$APPNAME/cli</CLICON_CLI_DIR>
|
||||||
|
|
@ -26,23 +28,21 @@ cat <<EOF > $cfg
|
||||||
<CLICON_XMLDB_DIR>/usr/local/var/$APPNAME</CLICON_XMLDB_DIR>
|
<CLICON_XMLDB_DIR>/usr/local/var/$APPNAME</CLICON_XMLDB_DIR>
|
||||||
<CLICON_XMLDB_PLUGIN>/usr/local/lib/xmldb/text.so</CLICON_XMLDB_PLUGIN>
|
<CLICON_XMLDB_PLUGIN>/usr/local/lib/xmldb/text.so</CLICON_XMLDB_PLUGIN>
|
||||||
<CLICON_RESTCONF_PRETTY>false</CLICON_RESTCONF_PRETTY>
|
<CLICON_RESTCONF_PRETTY>false</CLICON_RESTCONF_PRETTY>
|
||||||
<CLICON_NACM_MODE>internal</CLICON_NACM_MODE>
|
<CLICON_NACM_MODE>external</CLICON_NACM_MODE>
|
||||||
|
<CLICON_NACM_FILE>$nacmfile</CLICON_NACM_FILE>
|
||||||
</config>
|
</config>
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
cat <<EOF > $fyang
|
cat <<EOF > $fyang
|
||||||
module $APPNAME{
|
module $APPNAME{
|
||||||
prefix ex;
|
prefix ex;
|
||||||
import ietf-netconf-acm {
|
|
||||||
prefix nacm;
|
|
||||||
}
|
|
||||||
container authentication {
|
container authentication {
|
||||||
description "Example code for enabling www basic auth and some example
|
description "Example code for enabling www basic auth and some example
|
||||||
users";
|
users";
|
||||||
leaf basic_auth{
|
leaf basic_auth{
|
||||||
description "Basic user / password authentication as in HTTP basic auth";
|
description "Basic user / password authentication as in HTTP basic auth";
|
||||||
type boolean;
|
type boolean;
|
||||||
default false;
|
default true;
|
||||||
}
|
}
|
||||||
list auth {
|
list auth {
|
||||||
description "user / password entries. Valid if basic_auth=true";
|
description "user / password entries. Valid if basic_auth=true";
|
||||||
|
|
@ -64,21 +64,9 @@ module $APPNAME{
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
RULES=$(cat <<EOF
|
cat <<EOF > $nacmfile
|
||||||
<authentication>
|
|
||||||
<basic_auth>true</basic_auth>
|
|
||||||
<auth>
|
|
||||||
<user>adm1</user><password>bar</password>
|
|
||||||
</auth>
|
|
||||||
<auth>
|
|
||||||
<user>wilma</user><password>bar</password>
|
|
||||||
</auth>
|
|
||||||
<auth>
|
|
||||||
<user>guest</user><password>bar</password>
|
|
||||||
</auth>
|
|
||||||
</authentication>
|
|
||||||
<nacm>
|
<nacm>
|
||||||
<enable-nacm>false</enable-nacm>
|
<enable-nacm>true</enable-nacm>
|
||||||
<read-default>deny</read-default>
|
<read-default>deny</read-default>
|
||||||
<write-default>deny</write-default>
|
<write-default>deny</write-default>
|
||||||
<exec-default>deny</exec-default>
|
<exec-default>deny</exec-default>
|
||||||
|
|
@ -151,12 +139,10 @@ RULES=$(cat <<EOF
|
||||||
</rule>
|
</rule>
|
||||||
</rule-list>
|
</rule-list>
|
||||||
</nacm>
|
</nacm>
|
||||||
<x>0</x>
|
|
||||||
EOF
|
EOF
|
||||||
)
|
|
||||||
|
|
||||||
# kill old backend (if any)
|
# kill old backend (if any)
|
||||||
new "kill old backend"
|
new "kill old backend -zf $cfg -y $fyang"
|
||||||
sudo clixon_backend -zf $cfg -y $fyang
|
sudo clixon_backend -zf $cfg -y $fyang
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
err
|
err
|
||||||
|
|
@ -172,8 +158,8 @@ fi
|
||||||
new "kill old restconf daemon"
|
new "kill old restconf daemon"
|
||||||
sudo pkill -u www-data clixon_restconf
|
sudo pkill -u www-data clixon_restconf
|
||||||
sleep 1
|
sleep 1
|
||||||
new "start restconf daemon"
|
new "start restconf daemon (-a is enable http basic auth)"
|
||||||
sudo start-stop-daemon -S -q -o -b -x /www-data/clixon_restconf -d /www-data -c www-data -- -f $cfg -y $fyang
|
sudo start-stop-daemon -S -q -o -b -x /www-data/clixon_restconf -d /www-data -c www-data -- -f $cfg -y $fyang -- -a
|
||||||
|
|
||||||
sleep 1
|
sleep 1
|
||||||
|
|
||||||
|
|
@ -184,11 +170,8 @@ new2 "auth get"
|
||||||
expecteq "$(curl -u adm1:bar -sS -X GET http://localhost/restconf/data)" '{"data": null}
|
expecteq "$(curl -u adm1:bar -sS -X GET http://localhost/restconf/data)" '{"data": null}
|
||||||
'
|
'
|
||||||
|
|
||||||
new "auth set authentication config"
|
new "Set x to 0"
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><edit-config><target><candidate/></target><config>$RULES</config></edit-config></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
expecteq "$(curl -u adm1:bar -sS -X PUT -d '{"x": 0}' http://localhost/restconf/data/x)" ""
|
||||||
|
|
||||||
new "commit it"
|
|
||||||
expecteof "$clixon_netconf -qf $cfg -y $fyang" "<rpc><commit/></rpc>]]>]]>" "^<rpc-reply><ok/></rpc-reply>]]>]]>$"
|
|
||||||
|
|
||||||
new2 "auth get (no user: access denied)"
|
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"}}}
'
|
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"}}}
'
|
||||||
|
|
@ -200,11 +183,6 @@ new2 "auth get (access)"
|
||||||
expecteq "$(curl -u adm1:bar -sS -X GET http://localhost/restconf/data/x)" '{"x": 0}
|
expecteq "$(curl -u adm1:bar -sS -X GET http://localhost/restconf/data/x)" '{"x": 0}
|
||||||
'
|
'
|
||||||
|
|
||||||
#----------------Enable NACM
|
|
||||||
|
|
||||||
new "enable nacm"
|
|
||||||
expecteq "$(curl -u adm1:bar -sS -X PUT -d '{"enable-nacm": true}' http://localhost/restconf/data/nacm/enable-nacm)" ""
|
|
||||||
|
|
||||||
new2 "admin get nacm"
|
new2 "admin get nacm"
|
||||||
expecteq "$(curl -u adm1:bar -sS -X GET http://localhost/restconf/data/x)" '{"x": 0}
|
expecteq "$(curl -u adm1:bar -sS -X GET http://localhost/restconf/data/x)" '{"x": 0}
|
||||||
'
|
'
|
||||||
|
|
@ -214,7 +192,7 @@ expecteq "$(curl -u wilma:bar -sS -X GET http://localhost/restconf/data/x)" '{"x
|
||||||
'
|
'
|
||||||
|
|
||||||
new2 "guest get nacm"
|
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": "access denied"}}}
'
|
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"}}}
'
|
||||||
|
|
||||||
new "admin edit nacm"
|
new "admin edit nacm"
|
||||||
expecteq "$(curl -u adm1:bar -sS -X PUT -d '{"x": 1}' http://localhost/restconf/data/x)" ""
|
expecteq "$(curl -u adm1:bar -sS -X PUT -d '{"x": 1}' http://localhost/restconf/data/x)" ""
|
||||||
|
|
@ -223,7 +201,7 @@ 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"}}}
'
|
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"
|
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": "access denied"}}}
'
|
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"}}}
'
|
||||||
|
|
||||||
new "Kill restconf daemon"
|
new "Kill restconf daemon"
|
||||||
sudo pkill -u www-data clixon_restconf
|
sudo pkill -u www-data clixon_restconf
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue