Preparations for 6.2.0

Openssl 3.0 and autoconf 2.71
This commit is contained in:
Olof hagsand 2023-04-29 15:57:22 +02:00
parent 4643540391
commit 5d1c6b5759
8 changed files with 2764 additions and 2151 deletions

View file

@ -1,6 +1,6 @@
# Clixon Changelog
* [6.2.0](#620) Expected: April 2023
* [6.2.0](#620) 30 April 2023
* [6.1.0](#610) 19 Feb 2023
* [6.0.0](#600) 29 Nov 2022
* [5.9.0](#590) 24 September 2022
@ -40,9 +40,11 @@
* [3.3.1](#331) June 7 2017
## 6.2.0
Expected: April 2023
30 April 2023
### New features
Clixon 6.2.0 brings no new major feature changes, but completes YANG
schema mount and other features required by the clixon controller
project, along with minor improvements and bugfixes.
### API changes on existing protocol/config features
@ -73,13 +75,12 @@ Developers may need to change their code
### Minor features
* Removed previous backward compatible compile-time options introduced in 6.0:
* NETCONF_DEFAULT_RETRIEVAL_REPORT_AL
* AUTOCLI_OBSOLETE_SKIP
* Adjusted to Openssl 3.0
* Unified netconf input function
* Three different implementations were used in external, internal and controller code
* Internal netconf still not moved to unified
* The new clixon_netconf_input API unifies all three uses
* Code still experimental controlled by `NEW_NETCONF_INPUT`
* Code still experimental controlled by `NETCONF_INPUT_UNIFIED_INTERNAL`
* RFC 8528 YANG schema mount
* Made cli/autocli mount-point-aware
* Internal NETCONF (client <-> backend)
@ -92,7 +93,7 @@ Developers may need to change their code
### Corrected Bugs
* Fixed RESTCONF race conditions on SSL_shutdown sslerr ZERO_RETURN appears occasionally and exist.
* Fixed RESTCONF race conditions on SSL_shutdown sslerr ZERO_RETURN appears occasionally and exits.
* Fixed: RESTCONF: some client cert failure leads to restconf exit. Instead close and continue
## 6.1.0

View file

@ -13,9 +13,11 @@ See [documentation](https://clixon-docs.readthedocs.io), [project page](https://
Clixon is open-source and dual licensed. Either Apache License, Version 2.0 or GNU
General Public License Version 2; you choose, see [LICENSE.md](LICENSE.md).
Clixon has a master branch continuously tested with CI, but releases are made ca every second month. Latest 6.0.0 release is from November 2022. Next is planned for February 19 2023. See [CHANGELOG.md](CHANGELOG.md) release history.
Clixon has a master branch continuously tested with CI, but releases are made ca every second month, see [Releases](https://github.com/clicon/clixon/releases) and [CHANGELOG.md](CHANGELOG.md) release history.
Clixon interaction is best done posting issues, pull requests, or joining the
Matrix clixon forum https://matrix.to/#/#clixonforum:matrix.org.
Other clixon projects include [CLIgen](https://github.com/clicon/cligen), [the Clixon controller](https://github.com/clicon/clixon-controller), [clixon applications](https://github.com/clicon/clixon-examples) and others.
Clixon is sponsored by [Rubicon Communications LLC(Netgate)](https://www.netgate.com/) and [Akamai Technologies, Inc.](https://www.akamai.com).

View file

@ -380,143 +380,6 @@ netconf_input_packet(clicon_handle h,
return retval;
}
#ifndef NETCONF_INPUT_UNIFIED_EXTERN
/*! Process incoming frame, ie a char message framed by ]]>]]>
* Parse string to xml, check only one netconf message within a frame
* @param[in] h Clixon handle
* @param[in] cb Packet buffer
* @param[out] eof Set to 1 if pending close socket
* @retval 0 OK
* @retval -1 Fatal error
* @note there are errors detected here prior to whether you know what kind if message it is, and
* these errors are returned as "rpc-error".
* This is problematic since RFC6241 only says to return rpc-error on errors to <rpc>.
* Not at this early stage, the incoming message can be something else such as <hello> or
* something else.
* In section 8.1 regarding handling of <hello> it says just to "terminate" the session which I
* interpret as not sending anything back, just closing the session.
* Anyway, clixon therefore does the following on error:
* - Before we know what it is: send rpc-error
* - Hello messages: terminate
* - RPC messages: send rpc-error
*/
static int
netconf_input_frame1(clicon_handle h,
cbuf *cb,
int *eof)
{
int retval = -1;
char *str = NULL;
cxobj *xtop = NULL; /* Request (in) */
cxobj *xreq = NULL;
cxobj *xret = NULL; /* Return (out) */
cbuf *cbret = NULL;
yang_stmt *yspec;
int ret;
netconf_framing_type framing;
clicon_debug(CLIXON_DBG_DETAIL, "%s", __FUNCTION__);
clicon_debug(CLIXON_DBG_MSG, "Recv ext: %s", cbuf_get(cb));
framing = clicon_data_int_get(h, NETCONF_FRAMING_TYPE);
yspec = clicon_dbspec_yang(h);
if ((str = strdup(cbuf_get(cb))) == NULL){
clicon_err(OE_UNIX, errno, "strdup");
goto done;
}
/* Special case: */
if (strlen(str) == 0){
if ((cbret = cbuf_new()) == NULL){
clicon_err(OE_UNIX, errno, "cbuf_new");
goto done;
}
if (netconf_operation_failed(cbret, "rpc", "Empty XML")< 0)
goto done;
if (netconf_output_encap(framing, cbret) < 0)
goto done;
if (netconf_output(1, cbret, "rpc-error") < 0)
goto done;
goto ok;
}
/* Parse incoming XML message */
if ((ret = clixon_xml_parse_string(str, YB_RPC, yspec, &xtop, &xret)) < 0){
if ((cbret = cbuf_new()) == NULL){
clicon_err(OE_UNIX, errno, "cbuf_new");
goto done;
}
if (netconf_operation_failed(cbret, "rpc", clicon_err_reason)< 0)
goto done;
if (netconf_output_encap(framing, cbret) < 0)
goto done;
if (netconf_output(1, cbret, "rpc-error") < 0)
goto done;
goto ok;
}
if (ret == 0){
/* Note: xtop can be "hello" in which case one (maybe) should drop the session and log
* However, its not until netconf_input_packet that rpc vs hello vs other identification is
* actually made.
* Actually, there are no error replies to hello messages according to any RFC, so
* rpc error reply here is non-standard, but may be useful.
*/
if ((cbret = cbuf_new()) == NULL){
clicon_err(OE_XML, errno, "cbuf_new");
goto done;
}
if (clixon_xml2cbuf(cbret, xret, 0, 0, NULL, -1, 0) < 0)
goto done;
if (netconf_output_encap(framing, cbret) < 0)
goto done;
if (netconf_output(1, cbret, "rpc-error") < 0)
goto done;
goto ok;
}
/* Check for empty frame (no mesaages), return empty message, not clear from RFC what to do */
if (xml_child_nr_type(xtop, CX_ELMNT) == 0){
if ((cbret = cbuf_new()) == NULL){
clicon_err(OE_UNIX, errno, "cbuf_new");
goto done;
}
if (netconf_output_encap(framing, cbret) < 0)
goto done;
if (netconf_output(1, cbret, "rpc-error") < 0)
goto done;
goto ok;
}
/* Check for multi-messages in frame */
if (xml_child_nr_type(xtop, CX_ELMNT) != 1){
if ((cbret = cbuf_new()) == NULL){
clicon_err(OE_UNIX, errno, "cbuf_new");
goto done;
}
if (netconf_malformed_message(cbret, "More than one message in netconf rpc frame")< 0)
goto done;
if (netconf_output_encap(framing, cbret) < 0)
goto done;
if (netconf_output(1, cbret, "rpc-error") < 0)
goto done;
goto ok;
}
if ((xreq = xml_child_i_type(xtop, 0, CX_ELMNT)) == NULL){ /* Shouldnt happen */
clicon_err(OE_XML, EFAULT, "No xml req (shouldnt happen)");
goto done;
}
if (netconf_input_packet(h, xreq, yspec, eof) < 0)
goto done;
ok:
retval = 0;
done:
if (str)
free(str);
if (xtop)
xml_free(xtop);
if (xret)
xml_free(xret);
if (cbret)
cbuf_free(cbret);
return retval;
}
#endif /* NETCONF_INPUT_UNIFIED_EXTERN */
/*! Get netconf message: detect end-of-msg
* @param[in] s Socket where input arrived. read from this.
* @param[in] arg Clixon handle.
@ -528,7 +391,6 @@ netconf_input_frame1(clicon_handle h,
* <a>foo ..pause.. </a>]]>]]>
* then only "</a>" would be delivered to netconf_input_frame().
*/
#ifdef NETCONF_INPUT_UNIFIED_EXTERN
static int
netconf_input_cb(int s,
void *arg)
@ -659,137 +521,6 @@ netconf_input_cb(int s,
return retval;
}
#else /* NETCONF_INPUT_UNIFIED_EXTERN */
static int
netconf_input_cb(int s,
void *arg)
{
int retval = -1;
unsigned char buf[BUFSIZ]; /* from stdio.h, typically 8K */
clicon_handle h = arg;
cbuf *cb=NULL;
void *ptr;
size_t cdatlen = 0;
clicon_hash_t *cdat = clicon_data(h); /* Save cbuf between calls if not done */
int poll;
int i;
int len;
int frame_state;
size_t frame_size;
int ret;
int eof = 0; /* Set to 1 if pending close socket */
if (clicon_option_exists(h, NETCONF_FRAME_STATE) == 0)
frame_state = 0;
else
if ((frame_state = clicon_option_int(h, NETCONF_FRAME_STATE)) < 0)
goto done;
if (clicon_option_exists(h, NETCONF_FRAME_SIZE) == 0)
frame_size = 0;
else{
if ((ret = clicon_option_int(h, NETCONF_FRAME_SIZE)) < 0)
goto done;
frame_size = (size_t)ret;
}
if ((ptr = clicon_hash_value(cdat, NETCONF_FRAME_MSG, &cdatlen)) != NULL){
if (cdatlen != sizeof(cb)){
clicon_err(OE_XML, errno, "size mismatch %lu %lu",
(unsigned long)cdatlen, (unsigned long)sizeof(cb));
goto done;
}
cb = *(cbuf**)ptr;
clicon_hash_del(cdat, NETCONF_FRAME_MSG);
}
else{
if ((cb = cbuf_new()) == NULL){
clicon_err(OE_XML, errno, "cbuf_new");
goto done;
}
}
memset(buf, 0, sizeof(buf));
while (1){
if ((len = read(s, buf, sizeof(buf))) < 0){
if (errno == ECONNRESET)
len = 0; /* emulate EOF */
else{
clicon_log(LOG_ERR, "%s: read: %s", __FUNCTION__, strerror(errno));
goto done;
}
} /* read */
if (len == 0){ /* EOF */
clicon_debug(1, "%s len==0, closing", __FUNCTION__);
clixon_event_unreg_fd(s, netconf_input_cb);
close(s);
clixon_exit_set(1);
goto ok;
}
for (i=0; i<len; i++){
if (buf[i] == 0)
continue; /* Skip NULL chars (eg from terminals) */
if (clicon_data_int_get(h, NETCONF_FRAMING_TYPE) == NETCONF_SSH_CHUNKED){
/* Track chunked framing defined in RFC6242 */
if ((ret = netconf_input_chunked_framing(buf[i], &frame_state, &frame_size)) < 0)
goto done;
switch (ret){
case 1: /* chunk-data */
cprintf(cb, "%c", buf[i]);
break;
case 2: /* end-of-data */
/* Somewhat complex error-handling:
* Ignore packet errors, UNLESS an explicit termination request (eof)
*/
if (netconf_input_frame1(h, cb, &eof) < 0 &&
!ignore_packet_errors)
goto done;
if (eof)
goto done;
cbuf_reset(cb);
break;
default:
break;
}
}
else{
cprintf(cb, "%c", buf[i]);
if (detect_endtag("]]>]]>", buf[i], &frame_state)){
frame_state = 0;
/* OK, we have an xml string from a client */
/* Remove trailer */
*(((char*)cbuf_get(cb)) + cbuf_len(cb) - strlen("]]>]]>")) = '\0';
if (netconf_input_frame1(h, cb, &eof) < 0 &&
!ignore_packet_errors) // default is to ignore errors
goto done;
if (eof)
goto done;
cbuf_reset(cb);
}
}
}
/* poll==1 if more, poll==0 if none */
if ((poll = clixon_event_poll(s)) < 0)
goto done;
if (poll == 0){
/* No data to read, save data and continue on next round */
if (cbuf_len(cb) != 0){
if (clicon_hash_add(cdat, NETCONF_FRAME_MSG, &cb, sizeof(cb)) == NULL)
goto done;
cb = NULL;
}
break;
}
} /* while */
ok:
clicon_option_int_set(h, NETCONF_FRAME_STATE, frame_state);
clicon_option_int_set(h, NETCONF_FRAME_SIZE, frame_size);
retval = 0;
done:
if (cb)
cbuf_free(cb);
return retval;
}
#endif /* NETCONF_INPUT_UNIFIED_EXTERN */
/*! Send netconf hello message
* @param[in] h Clixon handle
* @param[in] s File descriptor to write on (eg 1 - stdout)

View file

@ -254,8 +254,13 @@ ssl_x509_name_oneline(SSL *ssl,
clicon_err(OE_RESTCONF, EINVAL, "ssl or cn is NULL");
goto done;
}
#if OPENSSL_VERSION_NUMBER < 0x30000000L
if ((cert = SSL_get_peer_certificate(ssl)) == NULL)
goto ok;
#else
if ((cert = SSL_get1_peer_certificate(ssl)) == NULL)
goto ok;
#endif
if ((name = X509_get_subject_name(cert)) == NULL)
goto ok;
if ((p = X509_NAME_oneline(name, NULL, 0)) == NULL)
@ -1355,10 +1360,16 @@ restconf_ssl_accept_client(clicon_handle h,
*/
if (restconf_auth_type_get(h) == CLIXON_AUTH_CLIENT_CERTIFICATE){
X509 *peercert;
// XXX SSL_get1_peer_certificate(ssl)
#if OPENSSL_VERSION_NUMBER < 0x30000000L
if ((peercert = SSL_get_peer_certificate(rc->rc_ssl)) != NULL){
X509_free(peercert);
}
#else
if ((peercert = SSL_get1_peer_certificate(rc->rc_ssl)) != NULL){
X509_free(peercert);
}
#endif
else { /* Get certificates (if available) */
if (proto != HTTP_2 &&
native_send_badrequest(h, rc->rc_s, rc->rc_ssl, "application/yang-data+xml",

4565
configure vendored

File diff suppressed because it is too large Load diff

View file

@ -38,7 +38,8 @@
# in the directory containing this script.
#
AC_INIT(lib/clixon/clixon.h.in)
AC_INIT
AC_CONFIG_SRCDIR([lib/clixon/clixon.h.in])
# Default CFLAGS and INSTALLFLAGS unless set by environment
: ${INSTALLFLAGS="-s"}
@ -148,7 +149,7 @@ AC_MSG_RESULT(LDFLAGS is $LDFLAGS)
AC_MSG_RESULT(INSTALLFLAGS is $INSTALLFLAGS)
AC_PROG_YACC
AC_PROG_LEX
AC_PROG_LEX(noyywrap)
if test "$LEX" = ":"; then
AC_MSG_ERROR(CLIXON does not find lex or flex.)
fi
@ -368,8 +369,8 @@ fi
# Checks for getsockopt options for getting unix socket peer credentials on
# Linux
AC_TRY_COMPILE([#include <sys/socket.h>], [getsockopt(1, SOL_SOCKET, SO_PEERCRED, 0, 0);], [AC_DEFINE(HAVE_SO_PEERCRED, 1, [Have getsockopt SO_PEERCRED])
AC_MSG_RESULT(Have getsockopt SO_PEERCRED)])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/socket.h>]], [[getsockopt(1, SOL_SOCKET, SO_PEERCRED, 0, 0);]])],[AC_DEFINE(HAVE_SO_PEERCRED, 1, [Have getsockopt SO_PEERCRED])
AC_MSG_RESULT(Have getsockopt SO_PEERCRED)],[])
# YANG_INSTALLDIR is where clixon installs the Clixon yang files and mandatory
# standard yang files: the files in in yang/clixon and yang/mandatory
@ -410,7 +411,7 @@ LIBDIR=`eval echo $libdir`
LIBDIR=`eval echo $LIBDIR`
LOCALSTATEDIR=`eval echo $localstatedir`
AC_OUTPUT(Makefile
AC_CONFIG_FILES([Makefile
lib/Makefile
lib/src/Makefile
lib/clixon/Makefile
@ -440,4 +441,5 @@ AC_OUTPUT(Makefile
test/config.sh
test/cicd/Makefile
test/vagrant/Makefile
)
])
AC_OUTPUT

View file

@ -197,24 +197,3 @@
* Introduced in 6.1, remove in 6.3
*/
#define AUTOCLI_DEPRECATED_HIDE
/*! Unified netconf input function
* Replace external, internal and controller netconf eventually
* New file: clixon_netconf_input.c with functions:
* - netconf_input_read2
* - netconf_input_msg2
* - netconf_input_frame2
* The following code should use this:
* X - netconf_main.c external netconf
* - netconf_proto.c internal netconf
* - controller device control
*/
/*! Use unified netconf input function for external use
* Introduced in 6.2
*/
#define NETCONF_INPUT_UNIFIED_EXTERN
/*! Use unified netconf input function for internal use
* Introduced in 6.2
*/
#undef NETCONF_INPUT_UNIFIED_INTERNAL

View file

@ -34,6 +34,8 @@ function memonce(){
valgrindtest=2 # This means backend valgrind test
: ${DEMWAIT:=10} # valgrind backend needs some time to get up
# trace-children=no for test_restconf_rpc.sh
sudo chown root $valgrindfile
sudo chmod 777 $valgrindfile
clixon_backend="/usr/bin/valgrind --num-callers=50 --leak-check=full --show-leak-kinds=all --suppressions=./valgrind-clixon.supp --track-fds=yes --trace-children=no --log-file=$valgrindfile clixon_backend"
;;
'restconf')