diff --git a/apps/backend/backend_handle.h b/apps/backend/backend_handle.h index f2acea6f..42c6c04d 100644 --- a/apps/backend/backend_handle.h +++ b/apps/backend/backend_handle.h @@ -2,7 +2,8 @@ * ***** BEGIN LICENSE BLOCK ***** - Copyright (C) 2009-2019 Olof Hagsand and Benny Holmgren + Copyright (C) 2009-2016 Olof Hagsand and Benny Holmgren + Copyright (C) 2017-2019 Olof Hagsand This file is part of CLIXON. diff --git a/apps/backend/clixon_backend_handle.c b/apps/backend/clixon_backend_handle.c index 6f5ca55e..19a936ed 100644 --- a/apps/backend/clixon_backend_handle.c +++ b/apps/backend/clixon_backend_handle.c @@ -2,7 +2,8 @@ * ***** BEGIN LICENSE BLOCK ***** - Copyright (C) 2009-2019 Olof Hagsand and Benny Holmgren + Copyright (C) 2009-2016 Olof Hagsand and Benny Holmgren + Copyright (C) 2017-2019 Olof Hagsand This file is part of CLIXON. diff --git a/apps/restconf/Makefile.in b/apps/restconf/Makefile.in index bd73ae91..3388b5a9 100644 --- a/apps/restconf/Makefile.in +++ b/apps/restconf/Makefile.in @@ -104,6 +104,7 @@ APPOBJ = $(APPSRC:.c=.o) # (eg restconf_method_notallowed) that uses symbols in restconf_api that # are not in the lib. LIBSRC = restconf_lib.c +LIBSRC += restconf_handle.c LIBOBJ = $(LIBSRC:.c=.o) diff --git a/apps/restconf/clixon_restconf.h b/apps/restconf/clixon_restconf.h index 8cf332d0..62cdf758 100644 --- a/apps/restconf/clixon_restconf.h +++ b/apps/restconf/clixon_restconf.h @@ -60,7 +60,8 @@ int get_user_cookie(char *cookiestr, char *attribute, char **val); int restconf_terminate(clicon_handle h); int restconf_insert_attributes(cxobj *xdata, cvec *qvec); int restconf_main_extension_cb(clicon_handle h, yang_stmt *yext, yang_stmt *ys); -char *clixon_restconf_param_get(clicon_handle h, char *param); -int clixon_restconf_param_set(clicon_handle h, char *param, char *val); +/* also in restconf_handle.h */ +char *restconf_param_get(clicon_handle h, char *param); +int restconf_param_set(clicon_handle h, char *param, char *val); #endif /* _CLIXON_RESTCONF_H_ */ diff --git a/apps/restconf/restconf_err.c b/apps/restconf/restconf_err.c index ff8c034c..6e38891a 100644 --- a/apps/restconf/restconf_err.c +++ b/apps/restconf/restconf_err.c @@ -98,7 +98,7 @@ restconf_badrequest(clicon_handle h, clicon_err(OE_UNIX, errno, "cbuf_new"); goto done; } - path = clixon_restconf_param_get("REQUEST_URI", r->envp); + path = restconf_param_get("REQUEST_URI", r->envp); if (restconf_reply_header(req, "Content-Type", "text/html") < 0) goto done; cprintf(cb, "The requested URL %s or data is in some way badly formed.\n", path); @@ -137,7 +137,7 @@ restconf_unauthorized(clicon_handle h, clicon_err(OE_UNIX, errno, "cbuf_new"); goto done; } - path = clixon_restconf_param_get("REQUEST_URI", r->envp); + path = restconf_param_get("REQUEST_URI", r->envp); if (restconf_reply_header(req, "Content-Type", "text/html") < 0) goto done; cprintf(cb, "access-denied\n"); @@ -175,7 +175,7 @@ restconf_forbidden(clicon_handle h, clicon_err(OE_UNIX, errno, "cbuf_new"); goto done; } - path = clixon_restconf_param_get("REQUEST_URI", r->envp); + path = restconf_param_get("REQUEST_URI", r->envp); if (restconf_reply_header(req, "Content-Type", "text/html") < 0) goto done; cprintf(cb, "The requested URL %s was forbidden.\n", path); @@ -213,7 +213,7 @@ restconf_notfound(clicon_handle h, clicon_err(OE_UNIX, errno, "cbuf_new"); goto done; } - path = clixon_restconf_param_get("REQUEST_URI", r->envp); + path = restconf_param_get("REQUEST_URI", r->envp); if (restconf_reply_header(req, "Content-Type", "text/html") < 0) goto done; cprintf(cb, "The requested URL %s was not found on this server.\n", path); @@ -270,7 +270,7 @@ restconf_notacceptable(clicon_handle h, clicon_err(OE_UNIX, errno, "cbuf_new"); goto done; } - path = clixon_restconf_param_get("REQUEST_URI", r->envp); + path = restconf_param_get("REQUEST_URI", r->envp); if (restconf_reply_header(req, "Content-Type", "text/html") < 0) goto done; cprintf(cb, "The target resource does not have a current representation that would be acceptable to the user agent.\n", path); @@ -338,7 +338,7 @@ restconf_internal_server_error(clicon_handle h, clicon_err(OE_UNIX, errno, "cbuf_new"); goto done; } - path = clixon_restconf_param_get("REQUEST_URI", r->envp); + path = restconf_param_get("REQUEST_URI", r->envp); if (restconf_reply_header(req, "Content-Type", "text/html") < 0) goto done; cprintf(cb, "Internal server error when accessing %s\n", path); diff --git a/apps/restconf/restconf_handle.c b/apps/restconf/restconf_handle.c new file mode 100644 index 00000000..53348b67 --- /dev/null +++ b/apps/restconf/restconf_handle.c @@ -0,0 +1,174 @@ +/* + * + ***** BEGIN LICENSE BLOCK ***** + + Copyright (C) 2009-2016 Olof Hagsand and Benny Holmgren + Copyright (C) 2017-2019 Olof Hagsand + 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 ***** + + */ + +#ifdef HAVE_CONFIG_H +#include "clixon_config.h" /* generated by config & autoconf */ +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* cligen */ +#include + +/* clicon */ +#include + +#include "restconf_handle.h" + +/* header part is copied from struct clicon_handle in lib/src/clixon_handle.c */ + +#define CLICON_MAGIC 0x99aafabe + +#define handle(h) (assert(clicon_handle_check(h)==0),(struct restconf_handle *)(h)) + +/* Clicon_handle for backends. + * First part of this is header, same for clicon_handle and cli_handle. + * Access functions for common fields are found in clicon lib: clicon_options.[ch] + * This file should only contain access functions for the _specific_ + * entries in the struct below. + */ +/*! Backend specific handle added to header CLICON handle + * This file should only contain access functions for the _specific_ + * entries in the struct below. + * @note The top part must be equivalent to struct clicon_handle in clixon_handle.c + * @see struct clicon_handle, struct cli_handle + */ +struct restconf_handle { + int rh_magic; /* magic (HDR)*/ + clicon_hash_t *rh_copt; /* clicon option list (HDR) */ + clicon_hash_t *rh_data; /* internal clicon data (HDR) */ + clicon_hash_t *rh_db_elmnt; /* xml datastore element cache data */ + event_stream_t *rh_stream; /* notification streams, see clixon_stream.[ch] */ + + /* ------ end of common handle ------ */ + clicon_hash_t *rh_params; /* restconf parameters, including http headers */ +}; + +/*! Creates and returns a clicon config handle for other CLICON API calls + */ +clicon_handle +restconf_handle_init(void) +{ + return clicon_handle_init0(sizeof(struct restconf_handle)); +} + +/*! Deallocates a backend handle, including all client structs + * @note: handle 'h' cannot be used in calls after this + * @see backend_client_rm + */ +int +restconf_handle_exit(clicon_handle h) +{ + clicon_handle_exit(h); /* frees h and options (and streams) */ + return 0; +} + +/*! Get restconf http parameter + * @param[in] h Clicon handle + * @param[in] name Data name + * @retval val Data value as string + * Currently using clixon runtime data but there is risk for colliding names + */ +char * +restconf_param_get(clicon_handle h, + char *param) +{ + struct restconf_handle *rh = handle(h); + + if (rh->rh_params == NULL) + return NULL; + return (char*)clicon_hash_value(rh->rh_params, param, NULL); +} + +/*! Set restconf http parameter + * @param[in] h Clicon handle + * @param[in] name Data name + * @param[in] val Data value as null-terminated string + * @retval 0 OK + * @retval -1 Error + * Currently using clixon runtime data but there is risk for colliding names + */ +int +restconf_param_set(clicon_handle h, + char *param, + char *val) +{ + struct restconf_handle *rh = handle(h); + + clicon_debug(1, "%s=%s", param, val); + if (rh->rh_params == NULL) + if ((rh->rh_params = clicon_hash_init()) == NULL) + return -1; + return clicon_hash_add(rh->rh_params, param, val, strlen(val)+1)==NULL?-1:0; +} + +/*! Delete all restconf http parameter + * @param[in] h Clicon handle + * @param[in] name Data name + * @retval 0 OK + * @retval -1 Error + * Currently using clixon runtime data but there is risk for colliding names + */ +int +restconf_param_del_all(clicon_handle h) +{ + int retval = -1; + struct restconf_handle *rh = handle(h); + + if (rh->rh_params != NULL){ + if (clicon_hash_free(rh->rh_params) < 0) + goto done; + rh->rh_params = NULL; + } + retval = 0; + done: + return retval; +} diff --git a/apps/restconf/restconf_handle.h b/apps/restconf/restconf_handle.h new file mode 100644 index 00000000..464dd50d --- /dev/null +++ b/apps/restconf/restconf_handle.h @@ -0,0 +1,51 @@ +/* + * + ***** BEGIN LICENSE BLOCK ***** + + Copyright (C) 2009-2016 Olof Hagsand and Benny Holmgren + Copyright (C) 2017-2019 Olof Hagsand + 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 ***** + + * + */ + +#ifndef _RESTCONF_HANDLE_H_ +#define _RESCTONF_HANDLE_H_ + +/* + * Prototypes + */ +clicon_handle restconf_handle_init(void); +int restconf_handle_exit(clicon_handle h); +char *restconf_param_get(clicon_handle h, char *param); +int restconf_param_set(clicon_handle h, char *param, char *val); +int restconf_param_del_all(clicon_handle h); + +#endif /* _RESTCONF_HANDLE_H_ */ diff --git a/apps/restconf/restconf_lib.c b/apps/restconf/restconf_lib.c index d325d11b..ea8b2cfe 100644 --- a/apps/restconf/restconf_lib.c +++ b/apps/restconf/restconf_lib.c @@ -60,6 +60,7 @@ #include #include "restconf_api.h" +#include "restconf_handle.h" #include "restconf_lib.h" /* See RFC 8040 Section 7: Mapping from NETCONF to Status Code @@ -188,10 +189,10 @@ restconf_media_int2str(restconf_media media) restconf_media restconf_content_type(clicon_handle h) { - char *str; + char *str = NULL; restconf_media m; - if ((str = clixon_restconf_param_get(h, "HTTP_CONTENT_TYPE")) == NULL) + if ((str = restconf_param_get(h, "HTTP_CONTENT_TYPE")) == NULL) return -1; if ((int)(m = restconf_media_str2int(str)) == -1) return -1; @@ -252,7 +253,7 @@ restconf_terminate(clicon_handle h) if ((x = clicon_conf_xml(h)) != NULL) xml_free(x); xpath_optimize_exit(); - clicon_handle_exit(h); + restconf_handle_exit(h); clicon_log_exit(); return 0; } @@ -412,53 +413,6 @@ restconf_main_extension_cb(clicon_handle h, return retval; } -/*! Get restconf http parameter - * @param[in] h Clicon handle - * @param[in] name Data name - * @retval val Data value as string - * Currently using clixon runtime data but there is risk for colliding names - */ -char * -clixon_restconf_param_get(clicon_handle h, - char *param) -{ - char *val; - if (clicon_data_get(h, param, &val) < 0) - return NULL; - return val; -} - -/*! Set restconf http parameter - * @param[in] h Clicon handle - * @param[in] name Data name - * @param[in] val Data value as null-terminated string - * @retval 0 OK - * @retval -1 Error - * Currently using clixon runtime data but there is risk for colliding names - */ -int -clixon_restconf_param_set(clicon_handle h, - char *param, - char *val) -{ - clicon_debug(1, "%s=%s", param, val); - return clicon_data_set(h, param, val); -} - -/*! Delete restconf http parameter - * @param[in] h Clicon handle - * @param[in] name Data name - * @retval 0 OK - * @retval -1 Error - * Currently using clixon runtime data but there is risk for colliding names - */ -int -clixon_restconf_param_del(clicon_handle h, - char *param) -{ - return clicon_data_del(h, param); -} - /*! Extract uri-encoded uri-path from fastcgi parameters * Use REQUEST_URI parameter and strip ?args * REQUEST_URI have args and is encoded @@ -473,7 +427,7 @@ restconf_uripath(clicon_handle h) char *path; char *q; - path = clixon_restconf_param_get(h, "REQUEST_URI"); + path = restconf_param_get(h, "REQUEST_URI"); if ((q = index(path, '?')) != NULL) *q = '\0'; return path; diff --git a/apps/restconf/restconf_lib.h b/apps/restconf/restconf_lib.h index f0a6c254..bdb7c021 100644 --- a/apps/restconf/restconf_lib.h +++ b/apps/restconf/restconf_lib.h @@ -64,9 +64,6 @@ int get_user_cookie(char *cookiestr, char *attribute, char **val); int restconf_terminate(clicon_handle h); int restconf_insert_attributes(cxobj *xdata, cvec *qvec); int restconf_main_extension_cb(clicon_handle h, yang_stmt *yext, yang_stmt *ys); -char *clixon_restconf_param_get(clicon_handle h, char *param); -int clixon_restconf_param_set(clicon_handle h, char *param, char *val); -int clixon_restconf_param_del(clicon_handle h, char *param); char *restconf_uripath(clicon_handle h); int restconf_drop_privileges(clicon_handle h, char *user); diff --git a/apps/restconf/restconf_main_evhtp.c b/apps/restconf/restconf_main_evhtp.c index dcc690ce..b42f39eb 100644 --- a/apps/restconf/restconf_main_evhtp.c +++ b/apps/restconf/restconf_main_evhtp.c @@ -54,6 +54,7 @@ #include #include #include +#include #include #include #include @@ -75,6 +76,7 @@ /* restconf */ #include "restconf_lib.h" /* generic shared with plugins */ +#include "restconf_handle.h" #include "restconf_api.h" /* generic not shared with plugins */ #include "restconf_root.h" @@ -202,6 +204,43 @@ query_iterator(evhtp_header_t *hdr, return 0; } +/*! Translate http header by capitalizing, prepend w HTTP_ and - -> _ + * Example: Host -> HTTP_HOST + */ +static int +convert_fcgi(evhtp_header_t *hdr, + void *arg) +{ + int retval = -1; + clicon_handle h = (clicon_handle)arg; + cbuf *cb = NULL; + int i; + char c; + + if ((cb = cbuf_new()) == NULL){ + clicon_err(OE_UNIX, errno, "cbuf_new"); + goto done; + } + /* convert key name */ + cprintf(cb, "HTTP_"); + for (i=0; ikey); i++){ + c = hdr->key[i] & 0xff; + if (islower(c)) + cprintf(cb, "%c", toupper(c)); + else if (c == '-') + cprintf(cb, "_"); + else + cprintf(cb, "%c", c); + } + if (restconf_param_set(h, cbuf_get(cb), hdr->val) < 0) + goto done; + retval = 0; + done: + if (cb) + cbuf_free(cb); + return retval; +} + /*! Map from evhtp information to "fcgi" type parameters used in clixon code * * While all these params come via one call in fcgi, the information must be taken from @@ -230,7 +269,6 @@ evhtp_params_set(clicon_handle h, htp_method meth; evhtp_uri_t *uri; evhtp_path_t *path; - evhtp_header_t *hdr; if ((uri = req->uri) == NULL){ clicon_err(OE_DAEMON, EFAULT, "No uri"); @@ -251,41 +289,17 @@ evhtp_params_set(clicon_handle h, clicon_err(OE_CFG, errno, "evhtp_kvs_for_each"); goto done; } - if (clixon_restconf_param_set(h, "REQUEST_METHOD", evhtp_method2str(meth)) < 0) + if (restconf_param_set(h, "REQUEST_METHOD", evhtp_method2str(meth)) < 0) goto done; - if (clixon_restconf_param_set(h, "REQUEST_URI", path->full) < 0) + if (restconf_param_set(h, "REQUEST_URI", path->full) < 0) goto done; - if (clixon_restconf_param_set(h, "HTTPS", "https") < 0) /* some string or NULL */ + if (restconf_param_set(h, "HTTPS", "https") < 0) /* some string or NULL */ + goto done; + /* Translate all http headers by capitalizing, prepend w HTTP_ and - -> _ + * Example: Host -> HTTP_HOST + */ + if (evhtp_headers_for_each(req->headers_in, convert_fcgi, h) < 0) goto done; - if ((hdr = evhtp_headers_find_header(req->headers_in, "Host")) != NULL){ - if (clixon_restconf_param_set(h, "HTTP_HOST", hdr->val) < 0) - goto done; - } - if ((hdr = evhtp_headers_find_header(req->headers_in, "Accept")) != NULL){ - if (clixon_restconf_param_set(h, "HTTP_ACCEPT", hdr->val) < 0) - goto done; - } - if ((hdr = evhtp_headers_find_header(req->headers_in, "Content-Type")) != NULL){ - if (clixon_restconf_param_set(h, "HTTP_CONTENT_TYPE", hdr->val) < 0) - goto done; - } - retval = 0; - done: - return retval; -} - -static int -evhtp_params_clear(clicon_handle h) -{ - int retval = -1; - char *params[] = {"QUERY_STRING", "REQUEST_METHOD", "REQUEST_URI", - "HTTPS", "HTTP_HOST", "HTTP_ACCEPT", "HTTP_CONTENT_TYPE", NULL}; - char *param; - int i=0; - - while((param=params[i]) != NULL) - if (clixon_restconf_param_del(h, param) < 0) - goto done; retval = 0; done: return retval; @@ -370,7 +384,7 @@ cx_path_wellknown(evhtp_request_t *req, goto done; /* Clear (fcgi) paramaters from this request */ - if (evhtp_params_clear(h) < 0) + if (restconf_param_del_all(h) < 0) goto done; done: return; /* void */ @@ -404,7 +418,7 @@ cx_path_restconf(evhtp_request_t *req, goto done; /* Clear (fcgi) paramaters from this request */ - if (evhtp_params_clear(h) < 0) + if (restconf_param_del_all(h) < 0) goto done; done: return; /* void */ @@ -473,7 +487,7 @@ main(int argc, clicon_log_init(__PROGRAM__, LOG_INFO, logdst); /* Create handle */ - if ((h = clicon_handle_init()) == NULL) + if ((h = restconf_handle_init()) == NULL) goto done; _CLICON_HANDLE = h; /* for termination handling */ diff --git a/apps/restconf/restconf_main_fcgi.c b/apps/restconf/restconf_main_fcgi.c index ebd0b56f..783653b3 100644 --- a/apps/restconf/restconf_main_fcgi.c +++ b/apps/restconf/restconf_main_fcgi.c @@ -78,6 +78,7 @@ /* restconf */ #include "restconf_lib.h" /* generic shared with plugins */ +#include "restconf_handle.h" #include "restconf_api.h" /* generic not shared with plugins */ #include "restconf_err.h" #include "restconf_root.h" /* generic not shared with plugins */ @@ -107,7 +108,7 @@ fcgi_params_set(clicon_handle h, for (i = 0; envp[i] != NULL; i++){ /* on the form = */ if (clixon_strsplit(envp[i], '=', ¶m, &val) < 0) goto done; - if (clixon_restconf_param_set(h, param, val) < 0) + if (restconf_param_set(h, param, val) < 0) goto done; if (param){ free(param); @@ -124,35 +125,6 @@ fcgi_params_set(clicon_handle h, return retval; } -/*! Clear all FCGI parameters in an environment - * @param[in] h Clixon handle - * @param[in] envp Fastcgi request handle parameter array on the format "=" - * @see https://nginx.org/en/docs/http/ngx_http_core_module.html#var_https - */ -static int -fcgi_params_clear(clicon_handle h, - char **envp) -{ - int retval = -1; - int i; - char *param = NULL; - - clicon_debug(1, "%s", __FUNCTION__); - for (i = 0; envp[i] != NULL; i++){ /* on the form = */ - if (clixon_strsplit(envp[i], '=', ¶m, NULL) < 0) - goto done; - if (clixon_restconf_param_del(h, param) < 0) - goto done; - if (param){ - free(param); - param = NULL; - } - } - retval = 0; - done: - return retval; -} - /* Need global variable to for signal handler XXX */ static clicon_handle _CLICON_HANDLE = NULL; @@ -246,7 +218,7 @@ main(int argc, clicon_log_init(__PROGRAM__, LOG_INFO, logdst); /* Create handle */ - if ((h = clicon_handle_init()) == NULL) + if ((h = restconf_handle_init()) == NULL) goto done; _CLICON_HANDLE = h; /* for termination handling */ @@ -504,12 +476,12 @@ main(int argc, */ if (fcgi_params_set(h, req->envp) < 0) goto done; - if ((path = clixon_restconf_param_get(h, "REQUEST_URI")) != NULL){ + if ((path = restconf_param_get(h, "REQUEST_URI")) != NULL){ clicon_debug(1, "path: %s", path); if (strncmp(path, "/" RESTCONF_API, strlen("/" RESTCONF_API)) == 0){ char *query = NULL; cvec *qvec = NULL; - query = clixon_restconf_param_get(h, "QUERY_STRING"); + query = restconf_param_get(h, "QUERY_STRING"); if (query != NULL && strlen(query)) if (str2cvec(query, '&', '=', &qvec) < 0) goto done; @@ -532,7 +504,7 @@ main(int argc, } else clicon_debug(1, "NULL URI"); - if (fcgi_params_clear(h, req->envp) < 0) + if (restconf_param_del_all(h) < 0) goto done; if (finish) FCGX_Finish_r(req); diff --git a/apps/restconf/restconf_methods.c b/apps/restconf/restconf_methods.c index 112ca34f..4a299a91 100644 --- a/apps/restconf/restconf_methods.c +++ b/apps/restconf/restconf_methods.c @@ -120,6 +120,7 @@ Mapping netconf error-tag -> status code #include #include "restconf_lib.h" +#include "restconf_handle.h" #include "restconf_api.h" #include "restconf_err.h" #include "restconf_methods.h" diff --git a/apps/restconf/restconf_methods_get.c b/apps/restconf/restconf_methods_get.c index 8794d581..dbf58e1f 100644 --- a/apps/restconf/restconf_methods_get.c +++ b/apps/restconf/restconf_methods_get.c @@ -58,6 +58,7 @@ #include #include "restconf_lib.h" +#include "restconf_handle.h" #include "restconf_api.h" #include "restconf_err.h" #include "restconf_methods_get.h" diff --git a/apps/restconf/restconf_methods_post.c b/apps/restconf/restconf_methods_post.c index 60580941..e85dad9f 100644 --- a/apps/restconf/restconf_methods_post.c +++ b/apps/restconf/restconf_methods_post.c @@ -60,6 +60,7 @@ #include #include "restconf_lib.h" +#include "restconf_handle.h" #include "restconf_api.h" #include "restconf_err.h" #include "restconf_methods_post.h" @@ -81,9 +82,9 @@ http_location_header(clicon_handle h, char *request_uri; cbuf *cb = NULL; - https = clixon_restconf_param_get(h, "HTTPS"); - host = clixon_restconf_param_get(h, "HTTP_HOST"); - request_uri = clixon_restconf_param_get(h, "REQUEST_URI"); + https = restconf_param_get(h, "HTTPS"); + host = restconf_param_get(h, "HTTP_HOST"); + request_uri = restconf_param_get(h, "REQUEST_URI"); if (xobj != NULL){ if ((cb = cbuf_new()) == NULL){ clicon_err(OE_UNIX, 0, "cbuf_new"); diff --git a/apps/restconf/restconf_root.c b/apps/restconf/restconf_root.c index d62f4797..8872e642 100644 --- a/apps/restconf/restconf_root.c +++ b/apps/restconf/restconf_root.c @@ -62,6 +62,7 @@ /* restconf */ #include "restconf_lib.h" +#include "restconf_handle.h" #include "restconf_api.h" #include "restconf_err.h" #include "restconf_root.h" @@ -89,7 +90,7 @@ api_well_known(clicon_handle h, errno = EINVAL; goto done; } - request_method = clixon_restconf_param_get(h, "REQUEST_METHOD"); + request_method = restconf_param_get(h, "REQUEST_METHOD"); if (strcmp(request_method, "GET") != 0){ restconf_method_notallowed(req, "GET"); goto ok; @@ -265,7 +266,7 @@ api_data(clicon_handle h, char *request_method; clicon_debug(1, "%s", __FUNCTION__); - request_method = clixon_restconf_param_get(h, "REQUEST_METHOD"); + request_method = restconf_param_get(h, "REQUEST_METHOD"); clicon_debug(1, "%s method:%s", __FUNCTION__, request_method); if (strcmp(request_method, "OPTIONS")==0) retval = api_data_options(h, req); @@ -355,7 +356,7 @@ api_root_restconf(clicon_handle h, errno = EINVAL; goto done; } - request_method = clixon_restconf_param_get(h, "REQUEST_METHOD"); + request_method = restconf_param_get(h, "REQUEST_METHOD"); path = restconf_uripath(h); pretty = clicon_option_bool(h, "CLICON_RESTCONF_PRETTY"); /* Get media for output (proactive negotiation) RFC7231 by using @@ -363,7 +364,7 @@ api_root_restconf(clicon_handle h, * operation POST, etc * If accept is * default is yang-json */ - if ((media_str = clixon_restconf_param_get(h, "HTTP_ACCEPT")) == NULL){ + if ((media_str = restconf_param_get(h, "HTTP_ACCEPT")) == NULL){ // retval = restconf_unsupported_media(r); // goto done; } diff --git a/apps/restconf/restconf_stream.c b/apps/restconf/restconf_stream.c index c6bc72ed..771c072e 100644 --- a/apps/restconf/restconf_stream.c +++ b/apps/restconf/restconf_stream.c @@ -86,6 +86,7 @@ #include /* Need to be after clixon_xml.h due to attribute format */ #include "restconf_lib.h" +#include "restconf_handle.h" #include "restconf_api.h" #include "restconf_err.h" #include "restconf_stream.h" @@ -376,7 +377,7 @@ api_stream(clicon_handle h, clicon_debug(1, "%s", __FUNCTION__); path = restconf_uripath(h); - query = clixon_restconf_param_get(h, "QUERY_STRING"); + query = restconf_param_get(h, "QUERY_STRING"); pretty = clicon_option_bool(h, "CLICON_RESTCONF_PRETTY"); if ((pvec = clicon_strsep(path, "/", &pn)) == NULL) goto done; diff --git a/example/main/example_restconf.c b/example/main/example_restconf.c index b5ca32b0..84eb48fa 100644 --- a/example/main/example_restconf.c +++ b/example/main/example_restconf.c @@ -214,7 +214,7 @@ example_restconf_credentials(clicon_handle h, if (basic_auth==0) goto ok; /* At this point in the code we must use HTTP basic authentication */ - if ((auth = clixon_restconf_param_get(h, "HTTP_AUTHORIZATION")) == NULL) + if ((auth = restconf_param_get(h, "HTTP_AUTHORIZATION")) == NULL) goto fail; if (strlen(auth) < strlen("Basic ")) goto fail; diff --git a/lib/clixon/clixon_handle.h b/lib/clixon/clixon_handle.h index 20f2dbcd..026159c1 100644 --- a/lib/clixon/clixon_handle.h +++ b/lib/clixon/clixon_handle.h @@ -2,7 +2,9 @@ * ***** BEGIN LICENSE BLOCK ***** - Copyright (C) 2009-2019 Olof Hagsand and Benny Holmgren + Copyright (C) 2009-2016 Olof Hagsand and Benny Holmgren + Copyright (C) 2017-2019 Olof Hagsand + Copyright (C) 2020 Olof Hagsand and Rubicon Communications, LLC(Netgate) This file is part of CLIXON. diff --git a/lib/clixon/clixon_hash.h b/lib/clixon/clixon_hash.h index 6fcca465..f4cd0ddd 100644 --- a/lib/clixon/clixon_hash.h +++ b/lib/clixon/clixon_hash.h @@ -45,13 +45,13 @@ struct clicon_hash { typedef struct clicon_hash *clicon_hash_t; clicon_hash_t *clicon_hash_init (void); -void clicon_hash_free (clicon_hash_t *); -clicon_hash_t clicon_hash_lookup (clicon_hash_t *head, const char *key); -void *clicon_hash_value (clicon_hash_t *head, const char *key, size_t *vlen); -clicon_hash_t clicon_hash_add (clicon_hash_t *head, const char *key, void *val, size_t vlen); -int clicon_hash_del (clicon_hash_t *head, const char *key); -int clicon_hash_dump(clicon_hash_t *head, FILE *f); -int clicon_hash_keys(clicon_hash_t *hash, char ***vector, size_t *nkeys); +int clicon_hash_free (clicon_hash_t *); +clicon_hash_t clicon_hash_lookup (clicon_hash_t *head, const char *key); +void *clicon_hash_value (clicon_hash_t *head, const char *key, size_t *vlen); +clicon_hash_t clicon_hash_add (clicon_hash_t *head, const char *key, void *val, size_t vlen); +int clicon_hash_del (clicon_hash_t *head, const char *key); +int clicon_hash_dump(clicon_hash_t *head, FILE *f); +int clicon_hash_keys(clicon_hash_t *hash, char ***vector, size_t *nkeys); /* * Macros to iterate over hash contents. diff --git a/lib/src/clixon_data.c b/lib/src/clixon_data.c index 4c24cab6..fe6aaaaf 100644 --- a/lib/src/clixon_data.c +++ b/lib/src/clixon_data.c @@ -93,13 +93,10 @@ clicon_data_get(clicon_handle h, { clicon_hash_t *cdat = clicon_data(h); - if (val == NULL){ - clicon_err(OE_CFG, EINVAL, "%s val is NULL", __FUNCTION__); - return -1; - } if (clicon_hash_lookup(cdat, (char*)name) == NULL) return -1; - *val = clicon_hash_value(cdat, (char*)name, NULL); + if (val) + *val = clicon_hash_value(cdat, (char*)name, NULL); return 0; } @@ -716,4 +713,3 @@ clicon_session_id_set(clicon_handle h, clicon_hash_add(cdat, "session-id", &id, sizeof(uint32_t)); return 0; } - diff --git a/lib/src/clixon_handle.c b/lib/src/clixon_handle.c index b4b5a303..f0ac5c65 100644 --- a/lib/src/clixon_handle.c +++ b/lib/src/clixon_handle.c @@ -2,7 +2,9 @@ * ***** BEGIN LICENSE BLOCK ***** - Copyright (C) 2009-2019 Olof Hagsand and Benny Holmgren + Copyright (C) 2009-2016 Olof Hagsand and Benny Holmgren + Copyright (C) 2017-2019 Olof Hagsand + Copyright (C) 2020 Olof Hagsand and Rubicon Communications, LLC(Netgate) This file is part of CLIXON. @@ -81,6 +83,7 @@ * XXX: put ch_stream under ch_data * @see struct cli_handle * @see struct backend_handle + * @see struct restconf_handle */ struct clicon_handle { int ch_magic; /* magic (HDR) */ @@ -157,7 +160,6 @@ clicon_handle_exit(clicon_handle h) clicon_hash_free(ha); if ((ha = clicon_data(h)) != NULL) clicon_hash_free(ha); - if ((ha = clicon_db_elmnt(h)) != NULL) clicon_hash_free(ha); stream_delete_all(h, 1); diff --git a/lib/src/clixon_hash.c b/lib/src/clixon_hash.c index f757743b..21b7b2d8 100644 --- a/lib/src/clixon_hash.c +++ b/lib/src/clixon_hash.c @@ -129,10 +129,11 @@ clicon_hash_init(void) /*! Free hash table. * - * @param[in] hash Hash table - * @retval void + * @param[in] hash Hash table + * @retval 0 OK + * @retval -1 Error */ -void +int clicon_hash_free(clicon_hash_t *hash) { int i; @@ -147,6 +148,7 @@ clicon_hash_free(clicon_hash_t *hash) } } free(hash); + return 0; } /*! Find hash key. @@ -189,6 +191,10 @@ clicon_hash_value(clicon_hash_t *hash, { clicon_hash_t h; + if (hash == NULL){ + clicon_err(OE_UNIX, EINVAL, "hash is NULL"); + return NULL; + } h = clicon_hash_lookup(hash, key); if (h == NULL) return NULL; /* OK, key not found */ @@ -218,6 +224,10 @@ clicon_hash_add(clicon_hash_t *hash, clicon_hash_t h; clicon_hash_t new = NULL; + if (hash == NULL){ + clicon_err(OE_UNIX, EINVAL, "hash is NULL"); + return NULL; + } /* Check NULL case */ if ((val == NULL && vlen != 0) || (val != NULL && vlen == 0)){ @@ -288,6 +298,10 @@ clicon_hash_del(clicon_hash_t *hash, { clicon_hash_t h; + if (hash == NULL){ + clicon_err(OE_UNIX, EINVAL, "hash is NULL"); + return -1; + } h = clicon_hash_lookup(hash, key); if (h == NULL) return -1; @@ -321,6 +335,10 @@ clicon_hash_keys(clicon_hash_t *hash, char **tmp; char **keys = NULL; + if (hash == NULL){ + clicon_err(OE_UNIX, EINVAL, "hash is NULL"); + return -1; + } *nkeys = 0; for (bkt = 0; bkt < HASH_SIZE; bkt++) { h = hash[bkt];