* RESTCONF failed authentication changed error return code from 403 Forbiden to 401 Unauthorized following RFC 8040

This commit is contained in:
Olof hagsand 2021-02-10 14:17:34 +01:00
parent 92a3898c46
commit 6b08a22f04
5 changed files with 22 additions and 6 deletions

View file

@ -31,6 +31,8 @@ Expected: February 2021
### New features ### New features
* RESTCONF failed authentication changed error return code from 403 Forbiden to 401 Unauthorized following RFC 8040
* Authentication OK but failed on access, remains as 403 Forbidden
* NETCONF Call Home Call Home RFC 8071 * NETCONF Call Home Call Home RFC 8071
* See [Netconf/ssh callhome](https://clixon-docs.readthedocs.io/en/latest/netconf.html#callhome) * See [Netconf/ssh callhome](https://clixon-docs.readthedocs.io/en/latest/netconf.html#callhome)
* Solution description using openssh and utility functions, no changes to core clixon * Solution description using openssh and utility functions, no changes to core clixon

View file

@ -430,6 +430,20 @@ api_return_err(clicon_handle h,
else{ else{
if ((code = restconf_err2code(tagstr)) < 0) if ((code = restconf_err2code(tagstr)) < 0)
code = 500; /* internal server error */ code = 500; /* internal server error */
if (code == 403){
/* Special case: netconf only has "access denied" while restconf
* differentiates between:
* 401 Unauthorized If the RESTCONF client is not authenticated (sec 2.5)
* 403 Forbidden If the user is not authorized to access a target resource or invoke
* an operation
*/
cxobj *xmsg;
char *mb;
if ((xmsg = xpath_first(xerr, NULL, "error-message")) != NULL &&
(mb = xml_body(xmsg)) != NULL &&
strcmp(mb, "The requested URL was unauthorized") == 0)
code = 401;
}
} }
if (restconf_reply_header(req, "Content-Type", "%s", restconf_media_int2str(media)) < 0) // XXX if (restconf_reply_header(req, "Content-Type", "%s", restconf_media_int2str(media)) < 0) // XXX
goto done; goto done;

View file

@ -81,8 +81,8 @@ static const map_str2int netconf_restconf_map[] = {
{"bad-element", 400}, {"bad-element", 400},
{"unknown-element", 400}, {"unknown-element", 400},
{"unknown-namespace", 400}, {"unknown-namespace", 400},
{"access-denied", 403}, {"access-denied", 403}, /* or 401 special case if tagstr is: "The requested URL was unauthorized" handled in api_return_err */
{"access-denied", 401}, /* or 403 */ {"access-denied", 401},
{"lock-denied", 409}, {"lock-denied", 409},
{"resource-denied", 409}, {"resource-denied", 409},
{"rollback-failed", 500}, {"rollback-failed", 500},

View file

@ -156,10 +156,10 @@ new "commit it"
expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><commit/></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$" expecteof "$clixon_netconf -qf $cfg" 0 "<rpc $DEFAULTNS><commit/></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$"
new "auth get (no user: access denied)" new "auth get (no user: access denied)"
expectpart "$(curl $CURLOPTS -X GET -H \"Accept:\ application/yang-data+json\" $RCPROTO://localhost/restconf/data)" 0 "HTTP/1.1 403 Forbidden" '{"ietf-restconf:errors":{"error":{"error-type":"protocol","error-tag":"access-denied","error-severity":"error","error-message":"The requested URL was unauthorized"}}} ' expectpart "$(curl $CURLOPTS -X GET -H \"Accept:\ application/yang-data+json\" $RCPROTO://localhost/restconf/data)" 0 "HTTP/1.1 401 Unauthorized" '{"ietf-restconf:errors":{"error":{"error-type":"protocol","error-tag":"access-denied","error-severity":"error","error-message":"The requested URL was unauthorized"}}} '
new "auth get (wrong passwd: access denied)" new "auth get (wrong passwd: access denied)"
expectpart "$(curl -u andy:foo $CURLOPTS -X GET $RCPROTO://localhost/restconf/data)" 0 "HTTP/1.1 403 Forbidden" '{"ietf-restconf:errors":{"error":{"error-type":"protocol","error-tag":"access-denied","error-severity":"error","error-message":"The requested URL was unauthorized"}}}' expectpart "$(curl -u andy:foo $CURLOPTS -X GET $RCPROTO://localhost/restconf/data)" 0 "HTTP/1.1 401 Unauthorized" '{"ietf-restconf:errors":{"error":{"error-type":"protocol","error-tag":"access-denied","error-severity":"error","error-message":"The requested URL was unauthorized"}}}'
new "auth get (access)" new "auth get (access)"
expectpart "$(curl -u andy:bar $CURLOPTS -X GET $RCPROTO://localhost/restconf/data/nacm-example:x)" 0 "HTTP/1.1 200 OK" '{"nacm-example:x":0}' expectpart "$(curl -u andy:bar $CURLOPTS -X GET $RCPROTO://localhost/restconf/data/nacm-example:x)" 0 "HTTP/1.1 200 OK" '{"nacm-example:x":0}'

View file

@ -168,10 +168,10 @@ new "Set x to 0"
expectpart "$(curl -u andy:bar $CURLOPTS -X PUT -H "Content-Type: application/yang-data+json" -d '{"nacm-example:x": 0}' $RCPROTO://localhost/restconf/data/nacm-example:x)" 0 "HTTP/1.1 201 Created" expectpart "$(curl -u andy:bar $CURLOPTS -X PUT -H "Content-Type: application/yang-data+json" -d '{"nacm-example:x": 0}' $RCPROTO://localhost/restconf/data/nacm-example:x)" 0 "HTTP/1.1 201 Created"
new "auth get (no user: access denied)" new "auth get (no user: access denied)"
expectpart "$(curl $CURLOPTS -X GET -H \"Accept:\ application/yang-data+json\" $RCPROTO://localhost/restconf/data)" 0 "HTTP/1.1 403 Forbidden" '{"ietf-restconf:errors":{"error":{"error-type":"protocol","error-tag":"access-denied","error-severity":"error","error-message":"The requested URL was unauthorized"}}}' expectpart "$(curl $CURLOPTS -X GET -H \"Accept:\ application/yang-data+json\" $RCPROTO://localhost/restconf/data)" 0 "HTTP/1.1 401 Unauthorized" '{"ietf-restconf:errors":{"error":{"error-type":"protocol","error-tag":"access-denied","error-severity":"error","error-message":"The requested URL was unauthorized"}}}'
new "auth get (wrong passwd: access denied)" new "auth get (wrong passwd: access denied)"
expectpart "$(curl -u andy:foo $CURLOPTS -X GET $RCPROTO://localhost/restconf/data)" 0 "HTTP/1.1 403 Forbidden" '{"ietf-restconf:errors":{"error":{"error-type":"protocol","error-tag":"access-denied","error-severity":"error","error-message":"The requested URL was unauthorized"}}}' expectpart "$(curl -u andy:foo $CURLOPTS -X GET $RCPROTO://localhost/restconf/data)" 0 "HTTP/1.1 401 Unauthorized" '{"ietf-restconf:errors":{"error":{"error-type":"protocol","error-tag":"access-denied","error-severity":"error","error-message":"The requested URL was unauthorized"}}}'
new "auth get (access)" new "auth get (access)"
expectpart "$(curl -u andy:bar $CURLOPTS -X GET $RCPROTO://localhost/restconf/data/nacm-example:x)" 0 "HTTP/1.1 200 OK" '{"nacm-example:x":0}' expectpart "$(curl -u andy:bar $CURLOPTS -X GET $RCPROTO://localhost/restconf/data/nacm-example:x)" 0 "HTTP/1.1 200 OK" '{"nacm-example:x":0}'