diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 18c53565..5aeea93e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,9 +2,9 @@ name: Clixon CI on: push: - branches: [ master ] + branches: [ master, http-data ] pull_request: - branches: [ master ] + branches: [ master, http-data ] jobs: build: diff --git a/CHANGELOG.md b/CHANGELOG.md index ace0acfd..3b4cbc11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,14 +39,16 @@ Expected: May 2022 ### New features -* Extended the Restconf implementation with a limited www-data +* Extended the Restconf implementation with a limited http-data static service * Added two new config options to clixon-config.yang: - * `CLICON_WWW_DATA_PATH` - * `CLICON_WWW_DATA_ROOT` - * The limited implemtation is as follows: - * path: Local files within `CLICON_WWW_DATA_ROOT` - * operation GET, HEAD, or OPTIONS - * query parameters not supported + * `CLICON_HTTP_DATA_PATH` + * `CLICON_HTTP_DATA_ROOT` + * Added feature http-data to restconf-config.yang and the following option: + * `enable-http-data` + * The limited implementation is as follows: + * path: Local static files within `CLICON_WWW_DATA_ROOT` + * operation GET, HEAD, or OPTIONS + * query parameters not supported 5. indata should be NULL (no write operations) 6. Limited media: text/html, JavaScript, image, and css 7. Authentication as restconf @@ -68,10 +70,12 @@ Users may have to change how they access the system * New `clixon-config@2022-03-21.yang` revision * Added option: * `CLICON_NETCONF_BASE_CAPABILITY` - * `CLICON_WWW_DATA_PATH` - * `CLICON_WWW_DATA_ROOT` - * Added feature: `www-data` - + * `CLICON_HTTP_DATA_PATH` + * `CLICON_HTTP_DATA_ROOT` +* New `clixon-restconf@2022-03-21.yang` revision + * Added option: + * `enable-http-data` + * Added feature: `http-data` * Netconf data-not-unique info changed to return schema nodes instead of XML for RFC7950 compliance * CLI reconnects to backend if backend restarts with a warning * Note that edits to the candidate database or locks will be lost diff --git a/apps/restconf/Makefile.in b/apps/restconf/Makefile.in index 29c09653..22c6eea2 100644 --- a/apps/restconf/Makefile.in +++ b/apps/restconf/Makefile.in @@ -98,7 +98,7 @@ APPSRC += restconf_methods_post.c APPSRC += restconf_methods_get.c APPSRC += restconf_methods_patch.c APPSRC += restconf_root.c -APPSRC += clixon_www_data.c +APPSRC += clixon_http_data.c APPSRC += restconf_main_$(with_restconf).c ifeq ($(with_restconf),native) APPSRC += restconf_http1.c diff --git a/apps/restconf/clixon_www_data.c b/apps/restconf/clixon_http_data.c similarity index 79% rename from apps/restconf/clixon_www_data.c rename to apps/restconf/clixon_http_data.c index 8dad80c1..b2b8f348 100644 --- a/apps/restconf/clixon_www_data.c +++ b/apps/restconf/clixon_http_data.c @@ -32,7 +32,7 @@ ***** END LICENSE BLOCK ***** * - * Limited www data handler embedded in restconf code + * Limited static http data service embedded in restconf code */ @@ -66,7 +66,23 @@ #include "restconf_handle.h" #include "restconf_api.h" #include "restconf_err.h" -#include "clixon_www_data.h" +#include "clixon_http_data.h" + +/* File extension <-> HTTP Content media mapping + * File extensions (on the left) MIME types (to the right) + * @see https://www.iana.org/assignments/media-types/media-types.xhtml + */ +static const map_str2str mime_map[] = { + {"html", "text/html"}, + {"css", "text/css"}, + {"eot", "application/vnd.ms-fontobject"}, + {"woff", "application/font-woff"}, + {"js", "application/javascript"}, + {"svg", "image/svg+xml"}, + {"ico", "image/x-icon"}, + {"woff2", "application/font-woff2"}, /* font/woff2? */ + { NULL, NULL} /* if not found: application/octet-stream */ +}; /*! Check if uri path denotes a data path * @@ -79,20 +95,20 @@ api_path_is_data(clicon_handle h, char **data) { char *path; - char *www_data_path; + char *http_data_path; if ((path = restconf_uripath(h)) == NULL) return 0; - if ((www_data_path = clicon_option_str(h, "CLICON_WWW_DATA_PATH")) == NULL) + if ((http_data_path = clicon_option_str(h, "CLICON_HTTP_DATA_PATH")) == NULL) return 0; - if (strlen(path) < 1 + strlen(www_data_path)) /* "/" + www_data_path */ + if (strlen(path) < strlen(http_data_path)) return 0; if (path[0] != '/') return 0; - if (strncmp(path+1, www_data_path, strlen(www_data_path)) != 0) + if (strncmp(path, http_data_path, strlen(http_data_path)) != 0) return 0; if (data) - *data = path + 1 + strlen(www_data_path); + *data = path + strlen(http_data_path); return 1; } @@ -103,7 +119,7 @@ api_path_is_data(clicon_handle h, * @see api_return_err */ static int -api_www_data_err(clicon_handle h, +api_http_data_err(clicon_handle h, void *req, int code) { @@ -144,10 +160,11 @@ api_www_data_err(clicon_handle h, * @param[in] pathname With stripped prefix (eg /data), ultimately a filename * @note: primitive file handling, just check if file exists and read it all * XXX 1: Buffer copying once too many, see #if 0 below - * XXX 2: Generic file system below CLICON_WWW_DATA_ROOT, no checks for links or .. + * XXX 2: Generic file system below CLICON_HTTP_DATA_ROOT, no checks for links or .. + * Need pathname santitization: no .. or ~, just a directory structure. */ static int -api_www_data_file(clicon_handle h, +api_http_data_file(clicon_handle h, void *req, char *pathname, int head) @@ -161,28 +178,37 @@ api_www_data_file(clicon_handle h, long fsize; size_t sz; char *www_data_root = NULL; + char *suffix; + char *media; if ((cbfile = cbuf_new()) == NULL){ clicon_err(OE_UNIX, errno, "cbuf_new"); goto done; } - if ((www_data_root = clicon_option_str(h, "CLICON_WWW_DATA_ROOT")) == NULL){ - clicon_err(OE_RESTCONF, ENOENT, "CLICON_WWW_DATA_ROOT missing"); + if ((www_data_root = clicon_option_str(h, "CLICON_HTTP_DATA_ROOT")) == NULL){ + clicon_err(OE_RESTCONF, ENOENT, "CLICON_HTTP_DATA_ROOT missing"); goto done; } - /* Need pathname santitization: no .. or ~, just a directory structure. - */ + + if ((suffix = rindex(pathname, '.')) == NULL){ + media = "application/octet-stream"; + } + else { + suffix++; + if ((media = clicon_str2str(mime_map, suffix)) == NULL) + media = "application/octet-stream"; + } cprintf(cbfile, "%s", www_data_root); if (pathname) cprintf(cbfile, "/%s", pathname); filename = cbuf_get(cbfile); if (stat(filename, &fstat) < 0){ - if (api_www_data_err(h, req, 404) < 0) /* not found */ + if (api_http_data_err(h, req, 404) < 0) /* not found */ goto done; goto ok; } if ((f = fopen(filename, "rb")) == NULL){ - if (api_www_data_err(h, req, 403) < 0) /* Forbidden or 500? */ + if (api_http_data_err(h, req, 403) < 0) /* Forbidden or 500? */ goto done; goto ok; } @@ -218,7 +244,7 @@ api_www_data_file(clicon_handle h, } } #endif - if (restconf_reply_header(req, "Content-Type", "%s", "text/html") < 0) + if (restconf_reply_header(req, "Content-Type", "%s", media) < 0) goto done; if (restconf_reply_send(req, 200, cbdata, head) < 0) goto done; @@ -235,11 +261,11 @@ api_www_data_file(clicon_handle h, return retval; } -/*! Gete data request +/*! Get data request * * This implementation is constrained as follows: - * 1. Enable as part of restconf and set feature www-data and CLICON_WWW_DATA_PATH - * 2. path: Local files within CLICON_WWW_DATA_ROOT + * 1. Enable as part of restconf and set feature www-data and CLICON_HTTP_DATA_PATH + * 2. path: Local files within CLICON_HTTP_DATA_ROOT * 3. operations: GET, HEAD, OPTIONS * 4. query parameters not supported * 5. indata should be NULL (no write operations) @@ -252,9 +278,9 @@ api_www_data_file(clicon_handle h, * Need to enable clixon-restconf.yang www-data feature */ int -api_www_data(clicon_handle h, - void *req, - cvec *qvec) +api_http_data(clicon_handle h, + void *req, + cvec *qvec) { int retval = -1; char *request_method = NULL; @@ -273,7 +299,7 @@ api_www_data(clicon_handle h, /* 1. path: with stripped prefix, ultimately: dir/filename */ if (!api_path_is_data(h, &pathname)){ - if (api_www_data_err(h, req, 404) < 0) /* not found */ + if (api_http_data_err(h, req, 404) < 0) /* not found */ goto done; goto ok; } @@ -288,13 +314,13 @@ api_www_data(clicon_handle h, options = 1; } else { - if (api_www_data_err(h, req, 405) < 0) /* method not allowed */ + if (api_http_data_err(h, req, 405) < 0) /* method not allowed */ goto done; goto ok; } /* 3. query parameters not accepted */ if (qvec != NULL){ - if (api_www_data_err(h, req, 400) < 0) /* bad request */ + if (api_http_data_err(h, req, 400) < 0) /* bad request */ goto done; goto ok; } @@ -304,7 +330,7 @@ api_www_data(clicon_handle h, goto done; } if (cbuf_len(indata)){ - if (api_www_data_err(h, req, 400) < 0) /* bad request */ + if (api_http_data_err(h, req, 400) < 0) /* bad request */ goto done; goto ok; } @@ -332,7 +358,7 @@ api_www_data(clicon_handle h, if (restconf_reply_send(req, 200, NULL, 0) < 0) goto done; } - else if (api_www_data_file(h, req, pathname, head) < 0) + else if (api_http_data_file(h, req, pathname, head) < 0) goto done; ok: retval = 0; diff --git a/apps/restconf/clixon_www_data.h b/apps/restconf/clixon_http_data.h similarity index 87% rename from apps/restconf/clixon_www_data.h rename to apps/restconf/clixon_http_data.h index fc971692..0174f0e1 100644 --- a/apps/restconf/clixon_www_data.h +++ b/apps/restconf/clixon_http_data.h @@ -32,16 +32,16 @@ ***** END LICENSE BLOCK ***** * - * Limited www data handler embedded in restconf code + * Limited static http data service embedded in restconf code */ -#ifndef _CLIXON_WWW_DATA_H_ -#define _CLIXON_WWW_DATA_H_ +#ifndef _CLIXON_HTTP_DATA_H_ +#define _CLIXON_HTTP_DATA_H_ /* * Prototypes */ int api_path_is_data(clicon_handle h, char **data); -int api_www_data(clicon_handle h, void *req, cvec *qvec); +int api_http_data(clicon_handle h, void *req, cvec *qvec); -#endif /* _CLIXON_WWW_DATA_H_ */ +#endif /* _CLIXON_HTTP_DATA_H_ */ diff --git a/apps/restconf/restconf_http1.c b/apps/restconf/restconf_http1.c index b0d238c1..f5ea9c6b 100644 --- a/apps/restconf/restconf_http1.c +++ b/apps/restconf/restconf_http1.c @@ -66,7 +66,7 @@ #include "restconf_err.h" #include "clixon_http1_parse.h" #include "restconf_http1.h" -#include "clixon_www_data.h" +#include "clixon_http_data.h" /* Size of xml read buffer */ #define BUFLEN 1024 @@ -428,7 +428,7 @@ restconf_http1_path_root(clicon_handle h, goto done; } else if (api_path_is_data(h, NULL)){ - if (api_www_data(h, sd, sd->sd_qvec) < 0) + if (api_http_data(h, sd, sd->sd_qvec) < 0) goto done; } else if (api_root_restconf(h, sd, sd->sd_qvec) < 0) /* error handling */ diff --git a/apps/restconf/restconf_nghttp2.c b/apps/restconf/restconf_nghttp2.c index acf3e005..008482d0 100644 --- a/apps/restconf/restconf_nghttp2.c +++ b/apps/restconf/restconf_nghttp2.c @@ -87,7 +87,7 @@ #include "restconf_native.h" /* Restconf-openssl mode specific headers*/ #ifdef HAVE_LIBNGHTTP2 /* Ends at end-of-file */ #include "restconf_nghttp2.h" /* Restconf-openssl mode specific headers*/ -#include "clixon_www_data.h" +#include "clixon_http_data.h" #define ARRLEN(x) (sizeof(x) / sizeof(x[0])) @@ -326,7 +326,7 @@ restconf_nghttp2_path(restconf_stream_data *sd) goto done; } else if (api_path_is_data(h, NULL)){ - if (api_www_data(h, sd, sd->sd_qvec) < 0) + if (api_http_data(h, sd, sd->sd_qvec) < 0) goto done; } else if (api_root_restconf(h, sd, sd->sd_qvec) < 0) /* error handling */ diff --git a/lib/clixon/clixon_string.h b/lib/clixon/clixon_string.h index 2bf4c6f7..1a6242a9 100644 --- a/lib/clixon/clixon_string.h +++ b/lib/clixon/clixon_string.h @@ -100,7 +100,8 @@ int uri_percent_decode(char *enc, char **str); const char *clicon_int2str(const map_str2int *mstab, int i); int clicon_str2int(const map_str2int *mstab, char *str); int clicon_str2int_search(const map_str2int *mstab, char *str, int upper); -int nodeid_split(char *nodeid, char **prefix, char **id); +char *clicon_str2str(const map_str2str *mstab, char *str); +int nodeid_split(char *nodeid, char **prefix, char **id); char *clixon_trim(char *str); char *clixon_trim2(char *str, char *trims); int clicon_strcmp(char *s1, char *s2); diff --git a/lib/src/clixon_string.c b/lib/src/clixon_string.c index e2844eaf..3e07ae87 100644 --- a/lib/src/clixon_string.c +++ b/lib/src/clixon_string.c @@ -787,6 +787,24 @@ clicon_str2int_search(const map_str2int *mstab, return -1; /* not found */ } +/*! Map from string to string using str2str map + * @param[in] mstab String, string map + * @param[in] str Input string + * @retval str Output string + * @retval NULL Error, not found + */ +char* +clicon_str2str(const map_str2str *mstab, + char *str) +{ + const struct map_str2str *ms; + + for (ms = &mstab[0]; ms->ms_s0; ms++) + if (strcmp(ms->ms_s0, str) == 0) + return ms->ms_s1; + return NULL; +} + /*! Split colon-separated node identifier into prefix and name * @param[in] node-id * @param[out] prefix If non-NULL, return malloced string, or NULL. diff --git a/test/test_http_data.sh b/test/test_http_data.sh new file mode 100755 index 00000000..717bc9e5 --- /dev/null +++ b/test/test_http_data.sh @@ -0,0 +1,158 @@ +#!/usr/bin/env bash +# Simple web data + +# Magic line must be first in script (see README.md) +s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi + +APPNAME=example + +cfg=$dir/conf.xml +wdir=$dir/www +rm -rf $wdir +mkdir $wdir + +# Does not work with fcgi +if [ "${WITH_RESTCONF}" = "fcgi" ]; then + echo "...skipped: Must run with --with-restconf=native" + if [ "$s" = $0 ]; then exit 0; else return 0; fi +fi + +RESTCONFIG=$(restconf_config none false) + + +# Clixon config +cat < $cfg + + $cfg + clixon-restconf:allow-auth-none + clixon-restconf:http-data + ${YANG_INSTALLDIR} + $IETFRFC + $dir + /usr/local/lib/$APPNAME/clispec + /usr/local/lib/$APPNAME/backend + example_backend.so$ + /usr/local/lib/$APPNAME/restconf + /data + $wdir + /usr/local/lib/$APPNAME/cli + $APPNAME + /usr/local/var/$APPNAME/$APPNAME.sock + /usr/local/var/$APPNAME/$APPNAME.pidfile + /usr/local/var/$APPNAME + true + $RESTCONFIG + +EOF + +# Host setup: +# / +# /var/www/html + +# Data file +cat < $wdir/index.html + + + +Welcome to Clixon! + + + +

Welcome to Clixon!

+

If you see this page, the clixon web server is successfully installed and +working. Further configuration is required.

+ + +EOF + +cat < $wdir/example.css +img { + display: inline; + border: + 0 none; +} +body { + font-family: verdana, arial, helvetica, sans-serif; + text-align: left; + position: relative; +} +table { + border-collapse: collapse; + text-align: left; +} +div, span { + text-align:left; +} + +h1,h2,h3,h4,h5,h6 { + color: white; +} +EOF + + +new "test params: -f $cfg" +if [ $BE -ne 0 ]; then + new "kill old backend" + sudo clixon_backend -zf $cfg + if [ $? -ne 0 ]; then + err + fi + sudo pkill -f clixon_backend # to be sure + + new "start backend -s init -f $cfg" + start_backend -s init -f $cfg +fi + +new "wait backend" +wait_backend + +if [ $RC -ne 0 ]; then + new "kill old restconf daemon" + stop_restconf_pre + + new "start restconf daemon" + start_restconf -f $cfg +fi + +new "wait restconf" +wait_restconf + +new "WWW get html" +expectpart "$(curl $CURLOPTS -X GET -H 'Accept: text/html' $RCPROTO://localhost/data/index.html)" 0 "HTTP/$HVER 200" "Content-Type: text/html" "Welcome to Clixon!" + +new "WWW get css" +expectpart "$(curl $CURLOPTS -X GET -H 'Accept: text/html' $RCPROTO://localhost/data/example.css)" 0 "HTTP/$HVER 200" "Content-Type: text/css" "display: inline;" --not-- "Content-Type: text/html" + +new "WWW head" +expectpart "$(curl $CURLOPTS --head -H 'Accept: text/html' $RCPROTO://localhost/data/index.html)" 0 "HTTP/$HVER 200" "Content-Type: text/html" --not-- "Welcome to Clixon!" + +new "WWW options" +expectpart "$(curl $CURLOPTS -X OPTIONS $RCPROTO://localhost/data/index.html)" 0 "HTTP/$HVER 200" "allow: OPTIONS,HEAD,GET" + +new "WWW get http not found" +expectpart "$(curl $CURLOPTS -X GET -H 'Accept: text/html' $RCPROTO://localhost/data/notfound.html)" 0 "HTTP/$HVER 404" "Content-Type: text/html" "404 Not Found" + +new "WWW post not allowed" +expectpart "$(curl $CURLOPTS -X POST -H 'Accept: text/html' -H "Content-Type: application/yang-data+json" -d '{"ietf-interfaces:interfaces":{"interface":{"name":"eth/0/0","type":"clixon-example:eth","enabled":true}}}' $RCPROTO://localhost/data/notfound.html)" 0 "HTTP/$HVER 405" "Content-Type: text/html" "405 Method Not Allowed" + +if [ $BE -ne 0 ]; then + new "Kill backend" + # Check if premature kill + pid=$(pgrep -u root -f clixon_backend) + if [ -z "$pid" ]; then + err "backend already dead" + fi + # kill backend + stop_backend -f $cfg +fi + +rm -rf $dir + +new "endtest" +endtest diff --git a/yang/clixon/Makefile.in b/yang/clixon/Makefile.in index 537b6d32..2f66b2e6 100644 --- a/yang/clixon/Makefile.in +++ b/yang/clixon/Makefile.in @@ -46,7 +46,7 @@ YANGSPECS = clixon-config@2022-03-21.yang # 5.7 YANGSPECS += clixon-lib@2021-12-05.yang # 5.5 YANGSPECS += clixon-rfc5277@2008-07-01.yang YANGSPECS += clixon-xml-changelog@2019-03-21.yang -YANGSPECS += clixon-restconf@2021-05-20.yang # 5.2 +YANGSPECS += clixon-restconf@2022-03-21.yang # 5.7 YANGSPECS += clixon-autocli@2022-02-11.yang # 5.6 all: diff --git a/yang/clixon/clixon-config@2022-03-21.yang b/yang/clixon/clixon-config@2022-03-21.yang index 2f184f61..4ea0af1f 100644 --- a/yang/clixon/clixon-config@2022-03-21.yang +++ b/yang/clixon/clixon-config@2022-03-21.yang @@ -50,10 +50,8 @@ module clixon-config { description "Added option: CLICON_NETCONF_BASE_CAPABILITY - CLICON_WWW_DATA_PATH - CLICON_WWW_DATA_ROOT - Added feature: - www-data + CLICON_HTTP_DATA_PATH + CLICON_HTTP_DATA_ROOT Released in Clixon 5.7"; } revision 2022-02-11 { @@ -216,20 +214,6 @@ module clixon-config { description "Released in Clixon 3.8"; } - feature www-data { - description - "This feature allows for a very limited www-data function as - addition to RESTCONF. - it is limited to: - 1. path: Local files within WWW_DATA_ROOT - 2. operation GET or HEAD - 3. query parameters not supported - 4. indata should be NULL (no write operations) - 5. Limited media: text/html, JavaScript, image, and css - 6. Authentication as restconf - 7. HTTP/1+2, TLS as restconf"; - } - extension search_index { description "This list argument acts as a search index using optimized binary search. "; @@ -619,14 +603,14 @@ module clixon-config { Note this also disables plain http/2 in prior-knowledge, that is, in http/2-only mode. HTTP/2 in https(TLS) is unaffected"; } - leaf CLICON_WWW_DATA_PATH { - if-feature "www-data"; + leaf CLICON_HTTP_DATA_PATH { + if-feature "clrc:http-data"; type string; description - "If set, enable www data on this sub-path"; + "If set, enable www data on this sub-path, must start with / (example: /data)"; } - leaf CLICON_WWW_DATA_ROOT { - if-feature "www-data"; + leaf CLICON_HTTP_DATA_ROOT { + if-feature "clrc:http-data"; type string; default "/var/www"; description diff --git a/yang/clixon/clixon-restconf@2022-03-21.yang b/yang/clixon/clixon-restconf@2022-03-21.yang new file mode 100644 index 00000000..d4996299 --- /dev/null +++ b/yang/clixon/clixon-restconf@2022-03-21.yang @@ -0,0 +1,284 @@ +module clixon-restconf { + yang-version 1.1; + namespace "http://clicon.org/restconf"; + prefix "clrc"; + + import ietf-inet-types { + prefix inet; + } + + organization + "Clixon"; + + contact + "Olof Hagsand "; + + description + "This YANG module provides a data-model for the Clixon RESTCONF daemon. + There is also clixon-config also including some restconf options. + The separation is not always logical but there are some reasons for the split: + 1. Some data (ie 'socket') is structurally complex and cannot be expressed as a + simple option + 2. clixon-restconf is defined as a macro/grouping and can be included in + other YANGs. In particular, it can be used inside a datastore, which + is not possible for clixon-config. + 3. Related to (2), options that should not be settable in a datastore should be + in clixon-config + + ***** BEGIN LICENSE BLOCK ***** + Copyright (C) 2020 Olof Hagsand and Rubicon Communications, LLC(Netgate) + + This file is part of CLIXON + + Licensed under the Apache License, Version 2.0 (the \"License\"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an \"AS IS\" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + Alternatively, the contents of this file may be used under the terms of + the GNU General Public License Version 3 or later (the \"GPL\"), + in which case the provisions of the GPL are applicable instead + of those above. If you wish to allow use of your version of this file only + under the terms of the GPL, and not to allow others to + use your version of this file under the terms of Apache License version 2, + indicate your decision by deleting the provisions above and replace them with + the notice and other provisions required by the GPL. If you do not delete + the provisions above, a recipient may use your version of this file under + the terms of any one of the Apache License version 2 or the GPL. + + ***** END LICENSE BLOCK *****"; + + revision 2022-03-21 { + description + "Added feature: + http-data - Limited static http server + Released in Clixon 5.7"; + } + revision 2021-05-20 { + description + "Added log-destination for restconf + Released in Clixon 5.2"; + } + revision 2021-03-15 { + description + "make authentication-type none a feature + Added flag to enable core dumps + Released in Clixon 5.1"; + } + revision 2020-12-30 { + description + "Added: debug field + Added 'none' as default value for auth-type + Changed http-auth-type enum from 'password' to 'user'"; + } + revision 2020-10-30 { + description + "Initial release"; + } + + feature fcgi { + description + "This feature indicates that the restconf server supports the fast-cgi reverse + proxy solution. + That is, a reverse proxy is the HTTP front-end and the restconf daemon listens + to a fcgi socket. + The alternative is the internal native HTTP solution."; + } + + feature allow-auth-none { + description + "This feature allows the use of authentication-type none."; + } + + feature http-data { + description + "This feature allows for a very limited static http-data function as + addition to RESTCONF. + It is limited to: + 1. path: Local static files within WWW_DATA_ROOT + 2. operation GET, HEAD, OPTIONS + 3. query parameters not supported + 4. indata should be NULL (no write operations) + 5. Limited media: text/html, JavaScript, image, and css + 6. Authentication as restconf + 7. HTTP/1+2, TLS as restconf"; + } + + typedef http-auth-type { + type enumeration { + enum none { + if-feature "allow-auth-none"; + description + "Incoming message are set to authenticated by default. No ca-auth callback is called, + Authenticated user is set to special user 'none'. + Typically assumes NACM is not enabled."; + } + enum client-certificate { + description + "TLS client certificate validation is made on each incoming message. If it passes + the authenticated user is extracted from the SSL_CN parameter + The ca-auth callback can be used to revise this behavior."; + } + enum user { + description + "User-defined authentication as defined by the ca-auth callback. + One example is some form of password authentication, such as basic auth."; + } + } + description + "Enumeration of HTTP authorization types."; + } + typedef log-destination { + type enumeration { + enum syslog { + description + "Log to syslog with: + ident: clixon_restconf and PID + facility: LOG_USER"; + } + enum file { + description + "Log to generated file at /var/log/clixon_restconf.log"; + } + } + } + grouping clixon-restconf{ + description + "HTTP RESTCONF configuration."; + leaf enable { + type boolean; + default "false"; + description + "Enables RESTCONF functionality. + Note that starting/stopping of a restconf daemon is different from it being + enabled or not. + For example, if the restconf daemon is under systemd management, the restconf + daemon will only start if enable=true."; + } + leaf enable-http-data { + type boolean; + default "false"; + if-feature "http-data"; + description + "Enables Limited static http-data functionality. + enable must be true for this option to be meaningful."; + } + leaf auth-type { + type http-auth-type; + description + "The authentication type. + Note client-certificate applies only if ssl-enable is true and socket has ssl"; + default user; + } + leaf debug { + description + "Set debug level of restconf daemon. + 0 is no debug, 1 is debugging, more is detailed debug. + Debug logs will be directed to log-destination with LOG_DEBUG level (for syslog)"; + type uint32; + default 0; + } + leaf log-destination { + description + "Log destination. + If debug is not set, only notice, error and warning will be logged"; + type log-destination; + default syslog; + } + leaf enable-core-dump { + description + "enable core dumps. + this is a no-op on systems that don't support it."; + type boolean; + default false; + } + leaf pretty { + type boolean; + default true; + description + "Restconf return value pretty print. + Restconf clients may add HTTP header: + Accept: application/yang-data+json, or + Accept: application/yang-data+xml + to get return value in XML or JSON. + RFC 8040 examples print XML and JSON in pretty-printed form. + Setting this value to false makes restconf return not pretty-printed + which may be desirable for performance or tests + This replaces the CLICON_RESTCONF_PRETTY option in clixon-config.yang"; + } + /* From this point only specific options + * First fcgi-specific options + */ + leaf fcgi-socket { + if-feature fcgi; /* Set by default by fcgi clixon_restconf daemon */ + type string; + default "/www-data/fastcgi_restconf.sock"; + description + "Path to FastCGI unix socket. Should be specified in webserver + Eg in nginx: fastcgi_pass unix:/www-data/clicon_restconf.sock + Only if with-restconf=fcgi, NOT native + This replaces CLICON_RESTCONF_PATH option in clixon-config.yang"; + } + /* Second, local native options */ + leaf server-cert-path { + type string; + description + "Path to server certificate file. + Note only applies if socket has ssl enabled"; + } + leaf server-key-path { + type string; + description + "Path to server key file + Note only applies if socket has ssl enabled"; + } + leaf server-ca-cert-path { + type string; + description + "Path to server CA cert file + Note only applies if socket has ssl enabled"; + } + list socket { + description + "List of server sockets that the restconf daemon listens to. + Not fcgi"; + key "namespace address port"; + leaf namespace { + type string; + description + "Network namespace. + On platforms where namespaces are not suppported, 'default' + Default value can be changed by RESTCONF_NETNS_DEFAULT"; + } + leaf address { + type inet:ip-address; + description "IP address to bind to"; + } + leaf port { + type inet:port-number; + description "TCP port to bind to"; + } + leaf ssl { + type boolean; + default true; + description "Enable for HTTPS otherwise HTTP protocol"; + } + } + } + container restconf { + description + "This presence is strictly not necessary since the enable flag + in clixon-restconf is the flag bearing the actual semantics. + However, removing the presence leads to default config in all + clixon installations, even those which do not use backend-started restconf. + One could see this as mostly cosmetically annoying. + Alternative would be to make the inclusion of this yang conditional."; + presence "Enables RESTCONF"; + uses clixon-restconf; + } +}