* Updated "evhtp" restconf mode
* No reliance on libevent or libevhtp, but on libssl >= 1.1 directly
* Moved out event handling to clixon event handling
* Moved out all ssl calls to clixon
* New code MUST use libevhtp from https://github.com/clixon/clixon-libevhtp.git
* This does NOT work: libevhtp from https://github.com/criticalstack/libevhtp.git
This commit is contained in:
parent
95a820c862
commit
c7e7598e3b
26 changed files with 1506 additions and 944 deletions
11
CHANGELOG.md
11
CHANGELOG.md
|
|
@ -31,8 +31,13 @@
|
|||
## 5.1.0
|
||||
Expected: April
|
||||
|
||||
### New features
|
||||
|
||||
|
||||
|
||||
### API changes on existing protocol/config features
|
||||
|
||||
* Restconf "evhtp" mode MUST use libevhtp from https://github.com/clixon/clixon-libevhtp.git instead from criticalstack
|
||||
* NETCONF Hello message semantics has been made stricter according to RFC 6241 Sec 8.1, for example:
|
||||
* A client MUST send a <hello> element.
|
||||
* Each peer MUST send at least the base NETCONF capability, "urn:ietf:params:netconf:base:1.1" (or 1.0 for RFC 4741)
|
||||
|
|
@ -59,6 +64,12 @@ Developers may need to change their code
|
|||
|
||||
### Minor features
|
||||
|
||||
* Updated "evhtp" restconf mode
|
||||
* No reliance on libevent or libevhtp, but on libssl >= 1.1 directly
|
||||
* Moved out event handling to clixon event handling
|
||||
* Moved out all ssl calls to clixon
|
||||
* New code MUST use libevhtp from https://github.com/clixon/clixon-libevhtp.git
|
||||
* This does NOT work: libevhtp from https://github.com/criticalstack/libevhtp.git
|
||||
* Application specialized error handling for specific error categories
|
||||
* See: https://clixon-docs.readthedocs.io/en/latest/misc.html#specialized-error-handling
|
||||
* Added several fields to process-control status operation: active, description, command, status, starttime, pid
|
||||
|
|
|
|||
|
|
@ -9,6 +9,9 @@ You choose.
|
|||
|
||||
Except as otherwise noted,
|
||||
- see lib/src/clixon_sha1.c
|
||||
- see apps/restconf/libevhtp_parser.[ch]
|
||||
BSD 3-clause: Copyright (c) 2010-2018, Mark Ellzey, Nathan French, Marcus Sundberg
|
||||
|
||||
|
||||
The two licenses are included below.
|
||||
|
||||
|
|
|
|||
|
|
@ -77,7 +77,6 @@ endif
|
|||
LIBDEPS = $(top_srcdir)/lib/src/$(CLIXON_LIB)
|
||||
|
||||
LIBS = -L$(top_srcdir)/lib/src $(top_srcdir)/lib/src/$(CLIXON_LIB) @LIBS@
|
||||
#LIBS += -lpthread -levent -levent_openssl -lssl -lcrypto
|
||||
|
||||
ifeq ($(LINKAGE),dynamic)
|
||||
CPPFLAGS = @CPPFLAGS@ -fPIC
|
||||
|
|
|
|||
|
|
@ -32,29 +32,25 @@
|
|||
|
||||
***** END LICENSE BLOCK *****
|
||||
|
||||
* Concrete functions for libevhtp of the
|
||||
* Concrete functions for openssl of the
|
||||
* Virtual clixon restconf API functions.
|
||||
* @see restconf_api.h for virtual API
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "clixon_config.h" /* generated by config & autoconf */
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <syslog.h>
|
||||
#include <fcntl.h>
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
#include <signal.h>
|
||||
#include <dlfcn.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/wait.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
/* evhtp */
|
||||
#include <evhtp/evhtp.h>
|
||||
#include <evhtp/sslutils.h>
|
||||
|
||||
/* cligen */
|
||||
#include <cligen/cligen.h>
|
||||
|
|
@ -65,15 +61,6 @@
|
|||
#include "restconf_lib.h"
|
||||
#include "restconf_api.h" /* Virtual api */
|
||||
|
||||
/* evhtp_safe_free is a macro that may not be present in a libevhtp release
|
||||
*/
|
||||
#ifndef evhtp_safe_free
|
||||
#define evhtp_safe_free(_var, _freefn) do { \
|
||||
_freefn((_var)); \
|
||||
(_var) = NULL; \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
/*! Add HTTP header field name and value to reply, evhtp specific
|
||||
* @param[in] req Evhtp http request handle
|
||||
* @param[in] name HTTP header field name
|
||||
|
|
@ -85,7 +72,6 @@ restconf_reply_header(void *req0,
|
|||
const char *name,
|
||||
const char *vfmt,
|
||||
...)
|
||||
|
||||
{
|
||||
evhtp_request_t *req = (evhtp_request_t *)req0;
|
||||
int retval = -1;
|
||||
|
|
@ -139,8 +125,9 @@ restconf_reply_send(void *req0,
|
|||
{
|
||||
evhtp_request_t *req = (evhtp_request_t *)req0;
|
||||
int retval = -1;
|
||||
struct evbuffer *eb = NULL;
|
||||
const char *reason_phrase;
|
||||
evhtp_connection_t *conn;
|
||||
struct evbuffer *eb = NULL;
|
||||
|
||||
req->status = code;
|
||||
if ((reason_phrase = restconf_code2reason(code)) == NULL)
|
||||
|
|
@ -149,17 +136,10 @@ restconf_reply_send(void *req0,
|
|||
if (restconf_reply_header(req, "Status", "%d %s", code, reason_phrase) < 0)
|
||||
goto done;
|
||||
#endif
|
||||
#if 0 /* Optional? */
|
||||
{
|
||||
evhtp_connection_t *conn;
|
||||
|
||||
if ((conn = evhtp_request_get_connection(req)) == NULL){
|
||||
clicon_err(OE_DAEMON, EFAULT, "evhtp_request_get_connection");
|
||||
goto done;
|
||||
}
|
||||
htp_sslutil_add_xheaders(req->headers_out, conn->ssl, HTP_SSLUTILS_XHDR_ALL);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If body, add a content-length header */
|
||||
if (cb != NULL && cbuf_len(cb)){
|
||||
|
|
@ -167,14 +147,13 @@ restconf_reply_send(void *req0,
|
|||
if (restconf_reply_header(req, "Content-Length", "%d", cbuf_len(cb)) < 0)
|
||||
goto done;
|
||||
}
|
||||
/* create evbuffer* : bufferevent_write_buffer/ drain,
|
||||
ie send everything , except body */
|
||||
evhtp_send_reply_start(req, req->status);
|
||||
evhtp_send_reply(req, req->status);
|
||||
|
||||
/* Write a body if cbuf is nonzero */
|
||||
if (cb != NULL && cbuf_len(cb)){
|
||||
/* Suboptimal, copy from cbuf to evbuffer */
|
||||
if ((eb = evbuffer_new()) == NULL){
|
||||
clicon_err(OE_CFG, errno, "evbuffer_new");
|
||||
clicon_err(OE_RESTCONF, errno, "evbuffer_new");
|
||||
goto done;
|
||||
}
|
||||
if (evbuffer_add(eb, cbuf_get(cb), cbuf_len(cb)) < 0){
|
||||
|
|
@ -217,3 +196,4 @@ restconf_get_indata(void *req0)
|
|||
|
||||
return cb;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,10 @@
|
|||
* @see restconf_api.h for virtual API
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "clixon_config.h" /* generated by config & autoconf */
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
|
|
|||
|
|
@ -36,6 +36,10 @@
|
|||
* @see RFC 7231 Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "clixon_config.h" /* generated by config & autoconf */
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
|
|
|||
|
|
@ -38,6 +38,10 @@
|
|||
* altogether?
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "clixon_config.h" /* generated by config & autoconf */
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
|
@ -52,6 +56,7 @@
|
|||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/wait.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
/* cligen */
|
||||
#include <cligen/cligen.h>
|
||||
|
|
@ -256,8 +261,8 @@ restconf_terminate(clicon_handle h)
|
|||
xpath_optimize_exit();
|
||||
restconf_handle_exit(h);
|
||||
clixon_err_exit();
|
||||
clicon_log_exit();
|
||||
clicon_debug(1, "%s done", __FUNCTION__);
|
||||
clicon_log_exit(); /* Must be after last clicon_debug */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -585,7 +590,7 @@ restconf_authentication_cb(clicon_handle h,
|
|||
goto done;
|
||||
}
|
||||
|
||||
/*! Basic config init
|
||||
/*! Basic config init, set auth-type, pretty, etc
|
||||
* @param[in] h Clixon handle
|
||||
* @param[in] xrestconf XML config containing clixon-restconf top-level
|
||||
* @retval -1 Error
|
||||
|
|
@ -636,3 +641,171 @@ restconf_config_init(clicon_handle h,
|
|||
retval = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*! Create and bind restconf socket
|
||||
*
|
||||
* @param[in] netns0 Network namespace, special value "default" is same as NULL
|
||||
* @param[in] addr Address as string, eg "0.0.0.0", "::"
|
||||
* @param[in] addrtype One of inet:ipv4-address or inet:ipv6-address
|
||||
* @param[in] port TCP port
|
||||
* @param[in] backlog Listen backlog, queie of pending connections
|
||||
* @param[in] flags Socket flags OR:ed in with the socket(2) type parameter
|
||||
* @param[out] ss Server socket (bound for accept)
|
||||
*/
|
||||
int
|
||||
restconf_socket_init(const char *netns0,
|
||||
const char *addr,
|
||||
const char *addrtype,
|
||||
uint16_t port,
|
||||
int backlog,
|
||||
int flags,
|
||||
int *ss)
|
||||
{
|
||||
int retval = -1;
|
||||
struct sockaddr * sa;
|
||||
struct sockaddr_in6 sin6 = { 0 };
|
||||
struct sockaddr_in sin = { 0 };
|
||||
size_t sin_len;
|
||||
const char *netns;
|
||||
|
||||
clicon_debug(1, "%s %s %s %s %hu", __FUNCTION__, netns0, addrtype, addr, port);
|
||||
/* netns default -> NULL */
|
||||
if (netns0 != NULL && strcmp(netns0, "default")==0)
|
||||
netns = NULL;
|
||||
else
|
||||
netns = netns0;
|
||||
if (strcmp(addrtype, "inet:ipv6-address") == 0) {
|
||||
sin_len = sizeof(struct sockaddr_in6);
|
||||
sin6.sin6_port = htons(port);
|
||||
sin6.sin6_family = AF_INET6;
|
||||
|
||||
inet_pton(AF_INET6, addr, &sin6.sin6_addr);
|
||||
sa = (struct sockaddr *)&sin6;
|
||||
}
|
||||
else if (strcmp(addrtype, "inet:ipv4-address") == 0) {
|
||||
sin_len = sizeof(struct sockaddr_in);
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = htons(port);
|
||||
sin.sin_addr.s_addr = inet_addr(addr);
|
||||
|
||||
sa = (struct sockaddr *)&sin;
|
||||
}
|
||||
else{
|
||||
clicon_err(OE_XML, EINVAL, "Unexpected addrtype: %s", addrtype);
|
||||
return -1;
|
||||
}
|
||||
if (clixon_netns_socket(netns, sa, sin_len, backlog, flags, ss) < 0)
|
||||
goto done;
|
||||
clicon_debug(1, "%s ss=%d", __FUNCTION__, *ss);
|
||||
retval = 0;
|
||||
done:
|
||||
clicon_debug(1, "%s %d", __FUNCTION__, retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Extract socket info from backend config
|
||||
* @param[in] h Clicon handle
|
||||
* @param[in] xs socket config
|
||||
* @param[in] nsc Namespace context
|
||||
* @param[out] namespace
|
||||
* @param[out] address Address as string, eg "0.0.0.0", "::"
|
||||
* @param[out] addrtype One of inet:ipv4-address or inet:ipv6-address
|
||||
* @param[out] port
|
||||
* @param[out] ssl
|
||||
*/
|
||||
int
|
||||
restconf_socket_extract(clicon_handle h,
|
||||
cxobj *xs,
|
||||
cvec *nsc,
|
||||
char **namespace,
|
||||
char **address,
|
||||
char **addrtype,
|
||||
uint16_t *port,
|
||||
uint16_t *ssl)
|
||||
{
|
||||
int retval = -1;
|
||||
cxobj *x;
|
||||
char *str = NULL;
|
||||
char *reason = NULL;
|
||||
int ret;
|
||||
char *body;
|
||||
cg_var *cv = NULL;
|
||||
yang_stmt *y;
|
||||
yang_stmt *ysub = NULL;
|
||||
|
||||
if ((x = xpath_first(xs, nsc, "namespace")) == NULL){
|
||||
clicon_err(OE_XML, EINVAL, "Mandatory namespace not given");
|
||||
goto done;
|
||||
}
|
||||
*namespace = xml_body(x);
|
||||
if ((x = xpath_first(xs, nsc, "address")) == NULL){
|
||||
clicon_err(OE_XML, EINVAL, "Mandatory address not given");
|
||||
goto done;
|
||||
}
|
||||
/* address is a union type and needs a special investigation to see which type (ipv4 or ipv6)
|
||||
* the address is
|
||||
*/
|
||||
body = xml_body(x);
|
||||
y = xml_spec(x);
|
||||
if ((cv = cv_dup(yang_cv_get(y))) == NULL){
|
||||
clicon_err(OE_UNIX, errno, "cv_dup");
|
||||
goto done;
|
||||
}
|
||||
if ((ret = cv_parse1(body, cv, &reason)) < 0){
|
||||
clicon_err(OE_XML, errno, "cv_parse1");
|
||||
goto done;
|
||||
}
|
||||
if (ret == 0){
|
||||
clicon_err(OE_XML, EFAULT, "%s", reason);
|
||||
goto done;
|
||||
}
|
||||
if ((ret = ys_cv_validate(h, cv, y, &ysub, &reason)) < 0)
|
||||
goto done;
|
||||
if (ret == 0){
|
||||
clicon_err(OE_XML, EFAULT, "Validation os address: %s", reason);
|
||||
goto done;
|
||||
}
|
||||
if (ysub == NULL){
|
||||
clicon_err(OE_XML, EFAULT, "No address union type");
|
||||
goto done;
|
||||
}
|
||||
*address = body;
|
||||
/* This is YANG type name of ip-address:
|
||||
* typedef ip-address {
|
||||
* type union {
|
||||
* type inet:ipv4-address; <---
|
||||
* type inet:ipv6-address; <---
|
||||
* }
|
||||
*/
|
||||
*addrtype = yang_argument_get(ysub);
|
||||
if ((x = xpath_first(xs, nsc, "port")) != NULL &&
|
||||
(str = xml_body(x)) != NULL){
|
||||
if ((ret = parse_uint16(str, port, &reason)) < 0){
|
||||
clicon_err(OE_XML, errno, "parse_uint16");
|
||||
goto done;
|
||||
}
|
||||
if (ret == 0){
|
||||
clicon_err(OE_XML, EINVAL, "Unrecognized value of port: %s", str);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
if ((x = xpath_first(xs, nsc, "ssl")) != NULL &&
|
||||
(str = xml_body(x)) != NULL){
|
||||
/* XXX use parse_bool but it is legacy static */
|
||||
if (strcmp(str, "false") == 0)
|
||||
*ssl = 0;
|
||||
else if (strcmp(str, "true") == 0)
|
||||
*ssl = 1;
|
||||
else {
|
||||
clicon_err(OE_XML, EINVAL, "Unrecognized value of ssl: %s", str);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
if (cv)
|
||||
cv_free(cv);
|
||||
if (reason)
|
||||
free(reason);
|
||||
return retval;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,6 +84,8 @@ char *restconf_uripath(clicon_handle h);
|
|||
int restconf_drop_privileges(clicon_handle h, char *user);
|
||||
int restconf_authentication_cb(clicon_handle h, void *req, int pretty, restconf_media media_out);
|
||||
int restconf_config_init(clicon_handle h, cxobj *xrestconf);
|
||||
int restconf_socket_init(const char *netns0, const char *addr, const char *addrtype, uint16_t port, int backlog, int flags, int *ss);
|
||||
int restconf_socket_extract(clicon_handle h, cxobj *xs, cvec *nsc, char **namespace, char **address, char **addrtype, uint16_t *port, uint16_t *ssl);
|
||||
|
||||
#endif /* _RESTCONF_LIB_H_ */
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
90
apps/restconf/restconf_openssl.h
Normal file
90
apps/restconf/restconf_openssl.h
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
*
|
||||
***** BEGIN LICENSE BLOCK *****
|
||||
|
||||
Copyright (C) 2009-2019 Olof Hagsand
|
||||
Copyright (C) 2020-2021 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 *****
|
||||
*
|
||||
* 1 1
|
||||
* +--------------------+ restconf_handle_get +--------------------+
|
||||
* | rh restconf_handle | <--------------------- | h clicon_handle |
|
||||
* +--------------------+ +--------------------+
|
||||
* common SSL config \ ^
|
||||
* \ | n
|
||||
* \ rh_sockets +--------------------+
|
||||
* +-----------> | rs restconf_socket |
|
||||
* +--------------------+
|
||||
* n per-socket SSL config
|
||||
* +--------------------+
|
||||
* | rr restconf_request| per-packet
|
||||
* +--------------------+
|
||||
*
|
||||
* Parse functions
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef _RESTCONF_OPENSSL_H_
|
||||
#define _RESTCONF_OPENSSL_H_
|
||||
|
||||
/*
|
||||
* Types
|
||||
*/
|
||||
/* Restconf request handle
|
||||
* Per socket request
|
||||
*/
|
||||
typedef struct {
|
||||
qelem_t rs_qelem; /* List header */
|
||||
clicon_handle rs_h; /* Clixon handle */
|
||||
int rs_ss; /* Server socket (ready for accept) */
|
||||
int rs_ssl; /* 0: Not SSL socket, 1:SSL socket */
|
||||
} restconf_socket;
|
||||
|
||||
/* Restconf handle
|
||||
* Global data about ssl (not per packet/request)
|
||||
*/
|
||||
typedef struct {
|
||||
SSL_CTX *rh_ctx; /* SSL context */
|
||||
evhtp_t *rh_evhtp; /* Evhtp struct */
|
||||
restconf_socket *rh_sockets; /* List of restconf server (ready for accept) sockets */
|
||||
} restconf_handle;
|
||||
|
||||
/*
|
||||
* Prototypes
|
||||
*/
|
||||
int restconf_parse(void *req, const char *buf, size_t buflen);
|
||||
|
||||
#endif /* _RESTCONF_OPENSSL_H_ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
231
configure
vendored
231
configure
vendored
|
|
@ -5044,28 +5044,13 @@ else
|
|||
fi
|
||||
|
||||
elif test "x${with_restconf}" == xevhtp; then
|
||||
for ac_header in evhtp/evhtp.h
|
||||
do :
|
||||
ac_fn_c_check_header_mongrel "$LINENO" "evhtp/evhtp.h" "ac_cv_header_evhtp_evhtp_h" "$ac_includes_default"
|
||||
if test "x$ac_cv_header_evhtp_evhtp_h" = xyes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_EVHTP_EVHTP_H 1
|
||||
_ACEOF
|
||||
|
||||
else
|
||||
as_fn_error $? "evhtp header missing. See https://github.com/clicon/libevhtp" "$LINENO" 5
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
#LIBS += -lpthread -levent -levent_openssl -lssl -lcrypto
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lpthread" >&5
|
||||
$as_echo_n "checking for pthread_create in -lpthread... " >&6; }
|
||||
if ${ac_cv_lib_pthread_pthread_create+:} false; then :
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for OPENSSL_init_ssl in -lssl" >&5
|
||||
$as_echo_n "checking for OPENSSL_init_ssl in -lssl... " >&6; }
|
||||
if ${ac_cv_lib_ssl_OPENSSL_init_ssl_+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ac_check_lib_save_LIBS=$LIBS
|
||||
LIBS="-lpthread $LIBS"
|
||||
LIBS="-lssl $LIBS"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
|
|
@ -5075,35 +5060,82 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
|||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char pthread_create ();
|
||||
char OPENSSL_init_ssl ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return pthread_create ();
|
||||
return OPENSSL_init_ssl ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
ac_cv_lib_pthread_pthread_create=yes
|
||||
ac_cv_lib_ssl_OPENSSL_init_ssl_=yes
|
||||
else
|
||||
ac_cv_lib_pthread_pthread_create=no
|
||||
ac_cv_lib_ssl_OPENSSL_init_ssl_=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
LIBS=$ac_check_lib_save_LIBS
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_create" >&5
|
||||
$as_echo "$ac_cv_lib_pthread_pthread_create" >&6; }
|
||||
if test "x$ac_cv_lib_pthread_pthread_create" = xyes; then :
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ssl_OPENSSL_init_ssl_" >&5
|
||||
$as_echo "$ac_cv_lib_ssl_OPENSSL_init_ssl_" >&6; }
|
||||
if test "x$ac_cv_lib_ssl_OPENSSL_init_ssl_" = xyes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_LIBPTHREAD 1
|
||||
#define HAVE_LIBSSL 1
|
||||
_ACEOF
|
||||
|
||||
LIBS="-lpthread $LIBS"
|
||||
LIBS="-lssl $LIBS"
|
||||
|
||||
else
|
||||
as_fn_error $? "libpthread missing" "$LINENO" 5
|
||||
as_fn_error $? "libssl missing" "$LINENO" 5
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for CRYPTO_new_ex_data in -lcrypto" >&5
|
||||
$as_echo_n "checking for CRYPTO_new_ex_data in -lcrypto... " >&6; }
|
||||
if ${ac_cv_lib_crypto_CRYPTO_new_ex_data+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ac_check_lib_save_LIBS=$LIBS
|
||||
LIBS="-lcrypto $LIBS"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char CRYPTO_new_ex_data ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return CRYPTO_new_ex_data ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
ac_cv_lib_crypto_CRYPTO_new_ex_data=yes
|
||||
else
|
||||
ac_cv_lib_crypto_CRYPTO_new_ex_data=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
LIBS=$ac_check_lib_save_LIBS
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_CRYPTO_new_ex_data" >&5
|
||||
$as_echo "$ac_cv_lib_crypto_CRYPTO_new_ex_data" >&6; }
|
||||
if test "x$ac_cv_lib_crypto_CRYPTO_new_ex_data" = xyes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_LIBCRYPTO 1
|
||||
_ACEOF
|
||||
|
||||
LIBS="-lcrypto $LIBS"
|
||||
|
||||
else
|
||||
as_fn_error $? "libcrypto missing" "$LINENO" 5
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for event_init in -levent" >&5
|
||||
|
|
@ -5153,146 +5185,19 @@ else
|
|||
as_fn_error $? "libevent missing" "$LINENO" 5
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for bufferevent_openssl_socket_new in -levent_openssl" >&5
|
||||
$as_echo_n "checking for bufferevent_openssl_socket_new in -levent_openssl... " >&6; }
|
||||
if ${ac_cv_lib_event_openssl_bufferevent_openssl_socket_new+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ac_check_lib_save_LIBS=$LIBS
|
||||
LIBS="-levent_openssl $LIBS"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char bufferevent_openssl_socket_new ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return bufferevent_openssl_socket_new ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
ac_cv_lib_event_openssl_bufferevent_openssl_socket_new=yes
|
||||
else
|
||||
ac_cv_lib_event_openssl_bufferevent_openssl_socket_new=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
LIBS=$ac_check_lib_save_LIBS
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_event_openssl_bufferevent_openssl_socket_new" >&5
|
||||
$as_echo "$ac_cv_lib_event_openssl_bufferevent_openssl_socket_new" >&6; }
|
||||
if test "x$ac_cv_lib_event_openssl_bufferevent_openssl_socket_new" = xyes; then :
|
||||
for ac_header in evhtp/evhtp.h
|
||||
do :
|
||||
ac_fn_c_check_header_mongrel "$LINENO" "evhtp/evhtp.h" "ac_cv_header_evhtp_evhtp_h" "$ac_includes_default"
|
||||
if test "x$ac_cv_header_evhtp_evhtp_h" = xyes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_LIBEVENT_OPENSSL 1
|
||||
#define HAVE_EVHTP_EVHTP_H 1
|
||||
_ACEOF
|
||||
|
||||
LIBS="-levent_openssl $LIBS"
|
||||
|
||||
else
|
||||
as_fn_error $? "libevent_openssl missing" "$LINENO" 5
|
||||
as_fn_error $? "evhtp header missing. See https://github.com/clicon/libevhtp" "$LINENO" 5
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for OPENSSL_init_ssl in -lssl" >&5
|
||||
$as_echo_n "checking for OPENSSL_init_ssl in -lssl... " >&6; }
|
||||
if ${ac_cv_lib_ssl_OPENSSL_init_ssl_+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ac_check_lib_save_LIBS=$LIBS
|
||||
LIBS="-lssl $LIBS"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char OPENSSL_init_ssl ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return OPENSSL_init_ssl ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
ac_cv_lib_ssl_OPENSSL_init_ssl_=yes
|
||||
else
|
||||
ac_cv_lib_ssl_OPENSSL_init_ssl_=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
LIBS=$ac_check_lib_save_LIBS
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ssl_OPENSSL_init_ssl_" >&5
|
||||
$as_echo "$ac_cv_lib_ssl_OPENSSL_init_ssl_" >&6; }
|
||||
if test "x$ac_cv_lib_ssl_OPENSSL_init_ssl_" = xyes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_LIBSSL 1
|
||||
_ACEOF
|
||||
|
||||
LIBS="-lssl $LIBS"
|
||||
|
||||
else
|
||||
as_fn_error $? "libssl missing" "$LINENO" 5
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for AES_encrypt in -lcrypto" >&5
|
||||
$as_echo_n "checking for AES_encrypt in -lcrypto... " >&6; }
|
||||
if ${ac_cv_lib_crypto_AES_encrypt+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ac_check_lib_save_LIBS=$LIBS
|
||||
LIBS="-lcrypto $LIBS"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char AES_encrypt ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return AES_encrypt ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
ac_cv_lib_crypto_AES_encrypt=yes
|
||||
else
|
||||
ac_cv_lib_crypto_AES_encrypt=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
LIBS=$ac_check_lib_save_LIBS
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_AES_encrypt" >&5
|
||||
$as_echo "$ac_cv_lib_crypto_AES_encrypt" >&6; }
|
||||
if test "x$ac_cv_lib_crypto_AES_encrypt" = xyes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_LIBCRYPTO 1
|
||||
_ACEOF
|
||||
|
||||
LIBS="-lcrypto $LIBS"
|
||||
|
||||
else
|
||||
as_fn_error $? "libcrypto missing" "$LINENO" 5
|
||||
fi
|
||||
done
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for evhtp_new in -levhtp" >&5
|
||||
$as_echo_n "checking for evhtp_new in -levhtp... " >&6; }
|
||||
|
|
|
|||
|
|
@ -211,13 +211,10 @@ if test "x${with_restconf}" == xfcgi; then
|
|||
# Lives in libfcgi-dev
|
||||
AC_CHECK_LIB(fcgi, FCGX_Init,, AC_MSG_ERROR([libfcgi-dev missing]))
|
||||
elif test "x${with_restconf}" == xevhtp; then
|
||||
AC_CHECK_HEADERS(evhtp/evhtp.h,, AC_MSG_ERROR([evhtp header missing. See https://github.com/clicon/libevhtp]))
|
||||
#LIBS += -lpthread -levent -levent_openssl -lssl -lcrypto
|
||||
AC_CHECK_LIB(pthread, pthread_create,, AC_MSG_ERROR([libpthread missing]))
|
||||
AC_CHECK_LIB(event, event_init,, AC_MSG_ERROR([libevent missing]))
|
||||
AC_CHECK_LIB(event_openssl, bufferevent_openssl_socket_new,, AC_MSG_ERROR([libevent_openssl missing]))
|
||||
AC_CHECK_LIB(ssl, OPENSSL_init_ssl ,, AC_MSG_ERROR([libssl missing]))
|
||||
AC_CHECK_LIB(crypto, AES_encrypt,, AC_MSG_ERROR([libcrypto missing]))
|
||||
AC_CHECK_LIB(crypto, CRYPTO_new_ex_data, , AC_MSG_ERROR([libcrypto missing]))
|
||||
AC_CHECK_LIB(event, event_init,, AC_MSG_ERROR([libevent missing]))
|
||||
AC_CHECK_HEADERS(evhtp/evhtp.h,, AC_MSG_ERROR([evhtp header missing. See https://github.com/clicon/libevhtp]))
|
||||
AC_CHECK_LIB(evhtp, evhtp_new,, AC_MSG_ERROR([libevhtp missing]),[-lpthread -levent -levent_openssl -lssl -lcrypto])
|
||||
|
||||
elif test "x${with_restconf}" == xno; then
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@ However, releases are made periodically (ca every 1 month) which is more tested.
|
|||
|
||||
A release branch can be made, eg release-4.0 where 4.0.0, 4.0.1 are tagged
|
||||
|
||||
Commit messages: https://chris.beams.io/posts/git-commit/
|
||||
|
||||
## How the autotools stuff works
|
||||
```
|
||||
configure.ac --.
|
||||
|
|
@ -190,5 +192,5 @@ Use MAXPATHLEN (not PATH_MAX) in sys/param.h
|
|||
|
||||
## Emulating a serial console
|
||||
|
||||
olof@alarik> socat PTY,link=/tmp/clixon-tty,rawer EXEC:"/usr/local/bin/clixon_cli -f /usr/local/etc/example.xml",pty,stderr &
|
||||
olof@alarik> screen /tmp/clixon-tty
|
||||
socat PTY,link=/tmp/clixon-tty,rawer EXEC:"/usr/local/bin/clixon_cli -f /usr/local/etc/example.xml",pty,stderr &
|
||||
screen /tmp/clixon-tty
|
||||
|
|
|
|||
|
|
@ -48,11 +48,7 @@ RUN apk add --update libevent cmake libevent-dev
|
|||
# clone libevhtp
|
||||
WORKDIR /clixon
|
||||
|
||||
#RUN git clone https://github.com/criticalstack/libevhtp.git
|
||||
#WORKDIR /clixon/libevhtp/build
|
||||
#RUN cmake -DEVHTP_DISABLE_REGEX=ON -DEVHTP_DISABLE_EVTHR=ON -DBUILD_SHARED_LIBS=OFF ..
|
||||
|
||||
RUN git clone https://github.com/clicon/libevhtp.git
|
||||
RUN git clone https://github.com/clicon/clixon-libevhtp.git
|
||||
WORKDIR /clixon/libevhtp
|
||||
RUN ./configure
|
||||
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@
|
|||
|
||||
/*
|
||||
* Types
|
||||
* Add error category here, but must also add an entry in EV variable.
|
||||
* Add error category here, but must also add an entry in EV variable in clixon_err.c
|
||||
*/
|
||||
enum clicon_err{
|
||||
/* 0 means error not set) */
|
||||
|
|
@ -71,6 +71,7 @@ enum clicon_err{
|
|||
OE_ROUTING, /* routing daemon error (eg quagga) */
|
||||
OE_XML, /* xml parsing etc */
|
||||
OE_SSL, /* Openssl errors, see eg ssl_get_error */
|
||||
OE_RESTCONF, /* RESTCONF errors */
|
||||
OE_PLUGIN, /* plugin loading, etc */
|
||||
OE_YANG , /* Yang error */
|
||||
OE_FATAL, /* Fatal error */
|
||||
|
|
|
|||
|
|
@ -9,6 +9,6 @@
|
|||
/*
|
||||
* Prototypes
|
||||
*/
|
||||
int clixon_netns_socket(const char *netns, struct sockaddr *sa, size_t sin_len, int backlog, int *sock);
|
||||
int clixon_netns_socket(const char *netns, struct sockaddr *sa, size_t sin_len, int backlog, int flags, int *sock);
|
||||
|
||||
#endif /* _CLIXON_NETNS_H_ */
|
||||
|
|
|
|||
|
|
@ -117,6 +117,7 @@ static struct errvec EV[] = {
|
|||
{"Routing demon error", OE_ROUTING},
|
||||
{"XML error", OE_XML},
|
||||
{"OpenSSL error", OE_SSL},
|
||||
{"RESTCONF error", OE_RESTCONF},
|
||||
{"Plugins", OE_PLUGIN},
|
||||
{"Yang error", OE_YANG},
|
||||
{"FATAL", OE_FATAL},
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ static FILE *_logfile = NULL;
|
|||
* if CLICON_LOG_SYSLOG, then print logs to syslog
|
||||
* You can do a combination of both
|
||||
* @code
|
||||
* clicon_log_init(h, __PROGRAM__, LOG_INFO, CLICON_LOG_STDERR);
|
||||
* clicon_log_init(__PROGRAM__, LOG_INFO, CLICON_LOG_STDERR);
|
||||
* @endcode
|
||||
*/
|
||||
int
|
||||
|
|
|
|||
|
|
@ -109,12 +109,14 @@ get_sock(int usock,
|
|||
* @param[in] sa Socketaddress
|
||||
* @param[in] sa_len Length of sa. Tecynicaliyu to be independent of sockaddr sa_len
|
||||
* @param[in] backlog Listen backlog, queie of pending connections
|
||||
* @param[in] flags Socket flags Or:ed in with the socket(2) type parameter
|
||||
* @param[out] sock Server socket (bound for accept)
|
||||
*/
|
||||
int
|
||||
static int
|
||||
create_socket(struct sockaddr *sa,
|
||||
size_t sin_len,
|
||||
int backlog,
|
||||
int flags,
|
||||
int *sock)
|
||||
{
|
||||
int retval = -1;
|
||||
|
|
@ -128,7 +130,7 @@ create_socket(struct sockaddr *sa,
|
|||
}
|
||||
/* create inet socket */
|
||||
if ((s = socket(sa->sa_family,
|
||||
SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC,
|
||||
SOCK_STREAM | SOCK_CLOEXEC | flags,
|
||||
0)) < 0) {
|
||||
clicon_err(OE_UNIX, errno, "socket");
|
||||
goto done;
|
||||
|
|
@ -141,6 +143,7 @@ create_socket(struct sockaddr *sa,
|
|||
clicon_err(OE_UNIX, errno, "setsockopt SO_REUSEADDR");
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* only bind ipv6, otherwise it may bind to ipv4 as well which is strange but seems default */
|
||||
if (sa->sa_family == AF_INET6 &&
|
||||
setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) == -1) {
|
||||
|
|
@ -171,13 +174,15 @@ create_socket(struct sockaddr *sa,
|
|||
* @param[in] sa Socketaddress
|
||||
* @param[in] sa_len Length of sa. Tecynicaliyu to be independent of sockaddr sa_len
|
||||
* @param[in] backlog Listen backlog, queie of pending connections
|
||||
* @param[in] flags Socket flags OR:ed in with the socket(2) type parameter
|
||||
* @param[out] sock Server socket (bound for accept)
|
||||
*/
|
||||
int
|
||||
static int
|
||||
fork_netns_socket(const char *netns,
|
||||
struct sockaddr *sa,
|
||||
size_t sin_len,
|
||||
int backlog,
|
||||
int flags,
|
||||
int *sock)
|
||||
{
|
||||
int retval = -1;
|
||||
|
|
@ -220,7 +225,7 @@ fork_netns_socket(const char *netns,
|
|||
#endif
|
||||
close(fd);
|
||||
/* Create socket in this namespace */
|
||||
if (create_socket(sa, sin_len, backlog, &s) < 0)
|
||||
if (create_socket(sa, sin_len, backlog, flags, &s) < 0)
|
||||
return -1;
|
||||
/* Send socket to parent */
|
||||
if (send_sock(sp[1], s) < 0)
|
||||
|
|
@ -247,6 +252,7 @@ fork_netns_socket(const char *netns,
|
|||
* @param[in] sa Socketaddress
|
||||
* @param[in] sa_len Length of sa. Tecynicaliyu to be independent of sockaddr sa_len
|
||||
* @param[in] backlog Listen backlog, queie of pending connections
|
||||
* @param[in] flags Socket flags OR:ed in with the socket(2) type parameter
|
||||
* @param[out] sock Server socket (bound for accept)
|
||||
*/
|
||||
int
|
||||
|
|
@ -254,19 +260,20 @@ clixon_netns_socket(const char *netns,
|
|||
struct sockaddr *sa,
|
||||
size_t sin_len,
|
||||
int backlog,
|
||||
int flags,
|
||||
int *sock)
|
||||
{
|
||||
int retval = -1;
|
||||
|
||||
clicon_debug(1, "%s", __FUNCTION__);
|
||||
if (netns == NULL){
|
||||
if (create_socket(sa, sin_len, backlog, sock) < 0)
|
||||
if (create_socket(sa, sin_len, backlog, flags, sock) < 0)
|
||||
goto done;
|
||||
goto ok;
|
||||
}
|
||||
else {
|
||||
#ifdef HAVE_SETNS
|
||||
if (fork_netns_socket(netns, sa, sin_len, backlog, sock) < 0)
|
||||
if (fork_netns_socket(netns, sa, sin_len, backlog, flags, sock) < 0)
|
||||
goto done;
|
||||
#else
|
||||
clicon_err(OE_UNIX, errno, "No namespace support on platform: %s", netns);
|
||||
|
|
|
|||
|
|
@ -1419,7 +1419,7 @@ xml_child_rm(cxobj *xp,
|
|||
/*! Remove this xml node from parent xml node. No freeing and node is new root
|
||||
* @param[in] xc xml child node to be removed
|
||||
* @retval 0 OK
|
||||
* @retval -1
|
||||
* @retval -1 Error
|
||||
* @note you should not remove xchild in loop (unless yoy keep track of xprev)
|
||||
*
|
||||
* @see xml_child_rm Remove a child of a node
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ if [ $BE -ne 0 ]; then
|
|||
start_backend -s init -f $cfg
|
||||
fi
|
||||
|
||||
new "waiting"
|
||||
new "wait backend"
|
||||
wait_backend
|
||||
|
||||
if [ $RC -ne 0 ]; then
|
||||
|
|
@ -157,11 +157,11 @@ if [ $RC -ne 0 ]; then
|
|||
|
||||
new "start restconf daemon"
|
||||
start_restconf -f $cfg
|
||||
|
||||
new "waiting"
|
||||
wait_restconf
|
||||
fi
|
||||
|
||||
new "wait restconf"
|
||||
wait_restconf
|
||||
|
||||
# Set nacm from scratch
|
||||
function nacm(){
|
||||
new "auth set authentication config"
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ if [ $BE -ne 0 ]; then
|
|||
start_backend -s init -f $cfg -- -sS $fstate
|
||||
fi
|
||||
|
||||
new "waiting"
|
||||
new "wait backend"
|
||||
wait_backend
|
||||
|
||||
if [ $RC -ne 0 ]; then
|
||||
|
|
@ -117,11 +117,11 @@ if [ $RC -ne 0 ]; then
|
|||
|
||||
new "start restconf daemon"
|
||||
start_restconf -f $cfg
|
||||
|
||||
new "waiting"
|
||||
wait_restconf
|
||||
fi
|
||||
|
||||
new "wait restconf"
|
||||
wait_restconf
|
||||
|
||||
new "generate 'large' config with $perfnr list entries"
|
||||
echo -n "$DEFAULTHELLO<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><interfaces xmlns=\"urn:example:clixon\"><a><name>foo</name><b>" > $fconfig
|
||||
for (( i=0; i<$perfnr; i++ )); do
|
||||
|
|
@ -189,7 +189,8 @@ new "cli get large config"
|
|||
$TIMEFN $clixon_cli -1f $cfg show state xml interfaces a foo b 2>&1 | awk '/real/ {print $2}'
|
||||
|
||||
# mem test needs sleep here
|
||||
sleep $DEMSLEEP
|
||||
new "wait restconf"
|
||||
wait_restconf
|
||||
|
||||
if [ $RC -ne 0 ]; then
|
||||
new "Kill restconf daemon"
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ if $IPv6; then
|
|||
EOF
|
||||
)
|
||||
else
|
||||
# For backend config, create 4 sockets, all combinations IPv4/IPv6 + http/https
|
||||
# For backend config, create 2 sockets, all combinations IPv4 + http/https
|
||||
RESTCONFIG1=$(cat <<EOF
|
||||
<restconf xmlns="http://clicon.org/restconf">
|
||||
<enable>true</enable>
|
||||
|
|
@ -152,7 +152,6 @@ function testrun()
|
|||
|
||||
new "start restconf daemon"
|
||||
start_restconf -f $cfg
|
||||
|
||||
fi
|
||||
|
||||
new "wait restconf"
|
||||
|
|
@ -161,6 +160,16 @@ function testrun()
|
|||
new "restconf root discovery. RFC 8040 3.1 (xml+xrd)"
|
||||
expectpart "$(curl $CURLOPTS -X GET $proto://$addr/.well-known/host-meta)" 0 'HTTP/1.1 200 OK' "<XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0'>" "<Link rel='restconf' href='/restconf'/>" "</XRD>"
|
||||
|
||||
# Negative test GET datastore
|
||||
if [ $proto = http ]; then # see (2) https to http port in restconf_main_openssl.c
|
||||
new "Wrong proto=https on http port, expect err 35 wrong version number"
|
||||
expectpart "$(curl $CURLOPTS -X GET https://$addr:80/.well-known/host-meta 2>&1)" 35 "wrong version number"
|
||||
else # see (1) http to https port in restconf_main_openssl.c
|
||||
new "Wrong proto=http on https port, expect bad request"
|
||||
expectpart "$(curl $CURLOPTS -X GET http://$addr:443/.well-known/host-meta)" 0 "HTTP/1.1 400 Bad Request"
|
||||
fi
|
||||
|
||||
# Exact match
|
||||
new "restconf get restconf resource. RFC 8040 3.3 (json)"
|
||||
expectpart "$(curl $CURLOPTS -X GET -H "Accept: application/yang-data+json" $proto://$addr/restconf)" 0 'HTTP/1.1 200 OK' '{"ietf-restconf:restconf":{"data":{},"operations":{},"yang-library-version":"2019-01-04"}}'
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
# - No restconf config means enable: false (extra rule)
|
||||
# See test_restconf_netns for network namespaces
|
||||
# XXX Lots of sleeps to remove race conditions. I am sure there are others way to fix this
|
||||
# XXX It is wrong to use $RESTCONF in clixon-config when using CLICON_BACKEND_RESTCONF_PROCESS
|
||||
# XXX the tests should be rewritten to use running datastore
|
||||
|
||||
# Magic line must be first in script (see README.md)
|
||||
s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi
|
||||
|
|
|
|||
|
|
@ -38,9 +38,9 @@ xusers="limited" # Set invalid cert
|
|||
# Whether to generate new keys or not (only if $dir is not removed)
|
||||
# Here dont generate keys if restconf started stand-alone (RC=0)
|
||||
: ${genkeys:=true}
|
||||
if [ $RC -eq 0 ]; then
|
||||
genkeys=false
|
||||
fi
|
||||
#if [ $RC -eq 0 ]; then
|
||||
# genkeys=false
|
||||
#fi
|
||||
|
||||
test -d $certdir || mkdir $certdir
|
||||
|
||||
|
|
@ -92,7 +92,6 @@ EOF
|
|||
)
|
||||
|
||||
if $genkeys; then
|
||||
|
||||
# Server certs
|
||||
. ./certs.sh
|
||||
|
||||
|
|
@ -103,7 +102,7 @@ if $genkeys; then
|
|||
prompt = no
|
||||
distinguished_name = dn
|
||||
[dn]
|
||||
CN = $name
|
||||
CN = $name # This can be verified using SSL_set1_host
|
||||
emailAddress = $name@foo.bar
|
||||
O = Clixon
|
||||
L = Stockholm
|
||||
|
|
@ -216,12 +215,17 @@ EOF
|
|||
echo "dummy" > $certdir/yyy.crt
|
||||
expectpart "$(curl $CURLOPTS --key $certdir/yyy.key --cert $certdir/yyy.crt -X GET $RCPROTO://localhost/restconf/data/example:x 2>&1)" 58 " could not load PEM client certificate"
|
||||
|
||||
new "Certificate required"
|
||||
expectpart "$(curl $CURLOPTS -X GET $RCPROTO://localhost/restconf/data/example:x 2>&1)" "35 55 56"
|
||||
# See (3) client-cert is NULL in restconf_main_openssl.c
|
||||
new "No cert: certificate required"
|
||||
expectpart "$(curl $CURLOPTS -X GET $RCPROTO://localhost/restconf/data/example:x 2>&1)" 0 "HTTP/1.1 400 Bad Request"
|
||||
|
||||
new "limited invalid cert"
|
||||
expectpart "$(curl $CURLOPTS --key $certdir/limited.key --cert $certdir/limited.crt -X GET $RCPROTO://localhost/restconf/data/example:x 2>&1)" "35 55 56" # 55 "certificate expired"
|
||||
|
||||
# Just ensure all is OK
|
||||
new "admin get x 42"
|
||||
expectpart "$(curl $CURLOPTS --key $certdir/andy.key --cert $certdir/andy.crt -X GET $RCPROTO://localhost/restconf/data/example:x)" 0 "HTTP/1.1 200 OK" '{"example:x":42}'
|
||||
|
||||
if [ $RC -ne 0 ]; then
|
||||
new "Kill restconf daemon"
|
||||
stop_restconf
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ case $release in
|
|||
$sshcmd sudo pkg install -y fcgi-devkit nginx
|
||||
;;
|
||||
evhtp)
|
||||
$sshcmd sudo pkg install -y libevent cmake libevhtp
|
||||
$sshcmd sudo pkg install -y libevent libevhtp
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
|
|
@ -204,7 +204,7 @@ case $release in
|
|||
evhtp)
|
||||
# $sshcmd sudo apt install -y libevent-2.1
|
||||
buildevhtp=true
|
||||
$sshcmd sudo apt install -y libevent-dev cmake libssl-dev
|
||||
$sshcmd sudo apt install -y libevent-dev libssl-dev
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
|
|
@ -234,7 +234,7 @@ case $release in
|
|||
$sshcmd sudo pacman -Syu --noconfirm nginx fcgi
|
||||
;;
|
||||
evhtp)
|
||||
$sshcmd sudo pacman -Syu --noconfirm libevent cmake
|
||||
$sshcmd sudo pacman -Syu --noconfirm libevent
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue