Imported Upstream version 2.7.1

This commit is contained in:
Laurent Bigonville 2013-11-24 16:00:12 +01:00
parent a1fa151fc7
commit 0121794af9
451 changed files with 41339 additions and 10887 deletions

View file

@ -1,9 +1,9 @@
# Makefile.in generated by automake 1.11.1 from Makefile.am.
# Makefile.in generated by automake 1.11.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
# Inc.
# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
# Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@ -18,6 +18,23 @@
# Network UPS Tools: server
VPATH = @srcdir@
am__make_dryrun = \
{ \
am__dry=no; \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
| grep '^AM OK$$' >/dev/null || am__dry=yes;; \
*) \
for am__flg in $$MAKEFLAGS; do \
case $$am__flg in \
*=*|--*) ;; \
*n*) am__dry=yes; break;; \
esac; \
done;; \
esac; \
test $$am__dry = yes; \
}
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
@ -59,8 +76,9 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_compare_version.m4 \
$(top_srcdir)/m4/nut_check_libltdl.m4 \
$(top_srcdir)/m4/nut_check_libneon.m4 \
$(top_srcdir)/m4/nut_check_libnetsnmp.m4 \
$(top_srcdir)/m4/nut_check_libnss.m4 \
$(top_srcdir)/m4/nut_check_libopenssl.m4 \
$(top_srcdir)/m4/nut_check_libpowerman.m4 \
$(top_srcdir)/m4/nut_check_libssl.m4 \
$(top_srcdir)/m4/nut_check_libusb.m4 \
$(top_srcdir)/m4/nut_check_libwrap.m4 \
$(top_srcdir)/m4/nut_check_os.m4 \
@ -109,6 +127,11 @@ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
$(LDFLAGS) -o $@
SOURCES = $(sockdebug_SOURCES) $(upsd_SOURCES)
DIST_SOURCES = $(sockdebug_SOURCES) $(upsd_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@ -117,6 +140,7 @@ ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AR = @AR@
ASCIIDOC = @ASCIIDOC@
ASPELL = @ASPELL@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
@ -143,6 +167,7 @@ DOC_BUILD_LIST = @DOC_BUILD_LIST@
DRIVER_BUILD_LIST = @DRIVER_BUILD_LIST@
DRIVER_INSTALL_TARGET = @DRIVER_INSTALL_TARGET@
DRIVER_MAN_LIST = @DRIVER_MAN_LIST@
DRVPATH = @DRVPATH@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
@ -345,8 +370,11 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
$(am__aclocal_m4_deps):
install-sbinPROGRAMS: $(sbin_PROGRAMS)
@$(NORMAL_INSTALL)
test -z "$(sbindir)" || $(MKDIR_P) "$(DESTDIR)$(sbindir)"
@list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \
$(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \
fi; \
for p in $$list; do echo "$$p $$p"; done | \
sed 's/$(EXEEXT)$$//' | \
while read p p1; do if test -f $$p || test -f $$p1; \
@ -386,10 +414,10 @@ clean-sbinPROGRAMS:
list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
echo " rm -f" $$list; \
rm -f $$list
sockdebug$(EXEEXT): $(sockdebug_OBJECTS) $(sockdebug_DEPENDENCIES)
sockdebug$(EXEEXT): $(sockdebug_OBJECTS) $(sockdebug_DEPENDENCIES) $(EXTRA_sockdebug_DEPENDENCIES)
@rm -f sockdebug$(EXEEXT)
$(LINK) $(sockdebug_OBJECTS) $(sockdebug_LDADD) $(LIBS)
upsd$(EXEEXT): $(upsd_OBJECTS) $(upsd_DEPENDENCIES)
upsd$(EXEEXT): $(upsd_OBJECTS) $(upsd_DEPENDENCIES) $(EXTRA_upsd_DEPENDENCIES)
@rm -f upsd$(EXEEXT)
$(LINK) $(upsd_OBJECTS) $(upsd_LDADD) $(LIBS)
@ -539,10 +567,15 @@ install-am: all-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:

View file

@ -145,13 +145,29 @@ static int parse_upsd_conf_args(int numargs, char **arg)
return 1;
}
#ifdef WITH_OPENSSL
/* CERTFILE <dir> */
if (!strcmp(arg[0], "CERTFILE")) {
free(certfile);
certfile = xstrdup(arg[1]);
return 1;
}
#elif (defined WITH_NSS) /* WITH_OPENSSL */
/* CERTPATH <dir> */
if (!strcmp(arg[0], "CERTPATH")) {
free(certfile);
certfile = xstrdup(arg[1]);
return 1;
}
#ifdef WITH_CLIENT_CERTIFICATE_VALIDATION
/* CERTREQUEST (0 | 1 | 2) */
if (!strcmp(arg[0], "CERTREQUEST")) {
certrequest = atoi(arg[1]);
return 1;
}
#endif /* WITH_CLIENT_CERTIFICATE_VALIDATION */
#endif /* WITH_OPENSSL | WITH_NSS */
/* ACCEPT <aclname> [<aclname>...] */
if (!strcmp(arg[0], "ACCEPT")) {
upslogx(LOG_WARNING, "ACCEPT in upsd.conf is no longer supported - switch to LISTEN");
@ -182,6 +198,17 @@ static int parse_upsd_conf_args(int numargs, char **arg)
upslogx(LOG_WARNING, "ACL in upsd.conf is no longer supported - switch to LISTEN");
return 1;
}
#ifdef WITH_NSS
/* CERTIDENT <name> <passwd> */
if (!strcmp(arg[0], "CERTIDENT")) {
free(certname);
certname = xstrdup(arg[1]);
free(certpasswd);
certpasswd = xstrdup(arg[2]);
return 1;
}
#endif /* WITH_NSS */
/* not recognized */
return 0;

View file

@ -19,6 +19,12 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef __cplusplus
/* *INDENT-OFF* */
extern "C" {
/* *INDENT-ON* */
#endif
/* read upsd.conf */
void load_upsdconf(int reloading);
@ -40,4 +46,11 @@ typedef struct ups_s {
void delete_acls(void);
void delete_access(void);
extern int num_ups;
extern int num_ups;
#ifdef __cplusplus
/* *INDENT-OFF* */
}
/* *INDENT-ON* */
#endif

View file

@ -1,4 +1,18 @@
#ifdef __cplusplus
/* *INDENT-OFF* */
extern "C" {
/* *INDENT-ON* */
#endif
void desc_load(void);
void desc_free(void);
const char *desc_get_cmd(const char *name);
const char *desc_get_var(const char *name);
#ifdef __cplusplus
/* *INDENT-OFF* */
}
/* *INDENT-ON* */
#endif

View file

@ -29,6 +29,12 @@
#define FLAG_USER 0x0001 /* username and password must be set */
#ifdef __cplusplus
/* *INDENT-OFF* */
extern "C" {
/* *INDENT-ON* */
#endif
struct {
const char *name;
void (*func)(nut_ctype_t *client, int numargs, const char **arg);
@ -56,3 +62,10 @@ struct {
{ NULL, (void(*)())(NULL), 0 }
};
#ifdef __cplusplus
/* *INDENT-OFF* */
}
/* *INDENT-ON* */
#endif

View file

@ -1 +1,14 @@
#ifdef __cplusplus
/* *INDENT-OFF* */
extern "C" {
/* *INDENT-ON* */
#endif
void net_get(nut_ctype_t *client, int numarg, const char **arg);
#ifdef __cplusplus
/* *INDENT-OFF* */
}
/* *INDENT-ON* */
#endif

View file

@ -1 +1,14 @@
#ifdef __cplusplus
/* *INDENT-OFF* */
extern "C" {
/* *INDENT-ON* */
#endif
void net_instcmd(nut_ctype_t *client, int numarg, const char **arg);
#ifdef __cplusplus
/* *INDENT-OFF* */
}
/* *INDENT-ON* */
#endif

View file

@ -1 +1,14 @@
#ifdef __cplusplus
/* *INDENT-OFF* */
extern "C" {
/* *INDENT-ON* */
#endif
void net_list(nut_ctype_t *client, int numarg, const char **arg);
#ifdef __cplusplus
/* *INDENT-OFF* */
}
/* *INDENT-ON* */
#endif

View file

@ -1,4 +1,17 @@
#ifdef __cplusplus
/* *INDENT-OFF* */
extern "C" {
/* *INDENT-ON* */
#endif
void net_ver(nut_ctype_t *client, int numarg, const char **arg);
void net_netver(nut_ctype_t *client, int numarg, const char **arg);
void net_help(nut_ctype_t *client, int numarg, const char **arg);
void net_fsd(nut_ctype_t *client, int numarg, const char **arg);
#ifdef __cplusplus
/* *INDENT-OFF* */
}
/* *INDENT-ON* */
#endif

View file

@ -1 +1,14 @@
#ifdef __cplusplus
/* *INDENT-OFF* */
extern "C" {
/* *INDENT-ON* */
#endif
void net_set(nut_ctype_t *client, int numarg, const char **arg);
#ifdef __cplusplus
/* *INDENT-OFF* */
}
/* *INDENT-ON* */
#endif

View file

@ -31,11 +31,27 @@
#include "neterr.h"
#include "netssl.h"
#ifdef WITH_NSS
#include <pk11pub.h>
#include <prinit.h>
#include <private/pprio.h>
#include <key.h>
#include <keyt.h>
#include <secerr.h>
#include <sslerr.h>
#endif /* WITH_NSS */
char *certfile = NULL;
char *certname = NULL;
char *certpasswd = NULL;
#ifdef WITH_CLIENT_CERTIFICATE_VALIDATION
int certrequest = 0;
#endif /* WITH_CLIENT_CERTIFICATE_VALIDATION */
static int ssl_initialized = 0;
#ifndef HAVE_SSL
#ifndef WITH_SSL
/* stubs for non-ssl compiles */
void net_starttls(nut_ctype_t *client, int numarg, const char **arg)
@ -68,8 +84,14 @@ void ssl_finish(nut_ctype_t *client)
}
}
void ssl_cleanup(void)
{
}
#else
#ifdef WITH_OPENSSL
static SSL_CTX *ssl_ctx = NULL;
static void ssl_debug(void)
@ -83,22 +105,156 @@ static void ssl_debug(void)
}
}
static int ssl_error(SSL *ssl, int ret)
{
int e;
e = SSL_get_error(ssl, ret);
switch (e)
{
case SSL_ERROR_WANT_READ:
upsdebugx(1, "ssl_error() ret=%d SSL_ERROR_WANT_READ", ret);
break;
case SSL_ERROR_WANT_WRITE:
upsdebugx(1, "ssl_error() ret=%d SSL_ERROR_WANT_WRITE", ret);
break;
case SSL_ERROR_SYSCALL:
if (ret == 0 && ERR_peek_error() == 0) {
upsdebugx(1, "ssl_error() EOF from client");
} else {
upsdebugx(1, "ssl_error() ret=%d SSL_ERROR_SYSCALL", ret);
}
break;
default:
upsdebugx(1, "ssl_error() ret=%d SSL_ERROR %d", ret, e);
ssl_debug();
}
return -1;
}
#elif defined(WITH_NSS) /* WITH_OPENSSL */
static CERTCertificate *cert;
static SECKEYPrivateKey *privKey;
static char *nss_password_callback(PK11SlotInfo *slot, PRBool retry,
void *arg)
{
if (retry) {
/* Force not inted to retrieve password many times. */
return NULL;
}
upslogx(LOG_INFO, "Intend to retrieve password for %s / %s: password %sconfigured",
PK11_GetSlotName(slot), PK11_GetTokenName(slot), certpasswd?"":"not ");
return certpasswd ? PL_strdup(certpasswd) : NULL;
}
static void nss_error(const char* text)
{
char buffer[SMALLBUF];
PRInt32 length = PR_GetErrorText(buffer);
if (length > 0 && length < SMALLBUF) {
upsdebugx(1, "nss_error %ld in %s : %s", (long)PR_GetError(), text, buffer);
}else{
upsdebugx(1, "nss_error %ld in %s", (long)PR_GetError(), text);
}
}
static int ssl_error(PRFileDesc *ssl, int ret)
{
char buffer[256];
PRInt32 length;
PRErrorCode e;
e = PR_GetError();
length = PR_GetErrorText(buffer);
if (length > 0 && length < 256) {
upsdebugx(1, "ssl_error() ret=%d %*s", e, length, buffer);
} else {
upsdebugx(1, "ssl_error() ret=%d", e);
}
return -1;
}
static SECStatus AuthCertificate(CERTCertDBHandle *arg, PRFileDesc *fd,
PRBool checksig, PRBool isServer)
{
nut_ctype_t *client = (nut_ctype_t *)SSL_RevealPinArg(fd);
SECStatus status = SSL_AuthCertificate(arg, fd, checksig, isServer);
upslogx(LOG_INFO, "Intend to authenticate client %s : %s.",
client?client->addr:"(unnamed)",
status==SECSuccess?"SUCCESS":"FAILED");
return status;
}
static SECStatus BadCertHandler(nut_ctype_t *arg, PRFileDesc *fd)
{
upslogx(LOG_WARNING, "Certificate validation failed for %s",
(arg&&arg->addr)?arg->addr:"<unnamed>");
#ifdef WITH_CLIENT_CERTIFICATE_VALIDATION
/* BadCertHandler is called when the NSS certificate validation is failed.
* If the certificate verification (user conf) is mandatory, reject authentication
* else accept it.
*/
return certrequest==NETSSL_CERTREQ_REQUIRE?SECFailure:SECSuccess;
#else /* WITH_CLIENT_CERTIFICATE_VALIDATION */
/* Always accept clients. */
return SECSuccess;
#endif /* WITH_CLIENT_CERTIFICATE_VALIDATION */
}
static void HandshakeCallback(PRFileDesc *fd, nut_ctype_t *client_data)
{
upslogx(LOG_INFO, "SSL handshake done successfully with client %s",
client_data->addr);
}
#endif /* WITH_OPENSSL | WITH_NSS */
void net_starttls(nut_ctype_t *client, int numarg, const char **arg)
{
#ifdef WITH_OPENSSL
int ret;
#elif defined(WITH_NSS) /* WITH_OPENSSL */
SECStatus status;
PRFileDesc *socket;
#endif /* WITH_OPENSSL | WITH_NSS */
if (client->ssl) {
send_err(client, NUT_ERR_ALREADY_SSL_MODE);
return;
}
if ((!ssl_ctx) || (!certfile) || (!ssl_initialized)) {
client->ssl_connected = 0;
if ((!certfile) || (!ssl_initialized)) {
send_err(client, NUT_ERR_FEATURE_NOT_CONFIGURED);
return;
}
#ifdef WITH_OPENSSL
if (!ssl_ctx) {
#elif defined(WITH_NSS) /* WITH_OPENSSL */
if (!NSS_IsInitialized()) {
#endif /* WITH_OPENSSL | WITH_NSS */
send_err(client, NUT_ERR_FEATURE_NOT_CONFIGURED);
ssl_initialized = 0;
return;
}
if (!sendback(client, "OK STARTTLS\n")) {
return;
}
#ifdef WITH_OPENSSL
client->ssl = SSL_new(ssl_ctx);
if (!client->ssl) {
@ -110,22 +266,126 @@ void net_starttls(nut_ctype_t *client, int numarg, const char **arg)
if (SSL_set_fd(client->ssl, client->sock_fd) != 1) {
upslog_with_errno(LOG_ERR, "SSL_set_fd failed\n");
ssl_debug();
return;
}
ret = SSL_accept(client->ssl);
switch (ret)
{
case 1:
client->ssl_connected = 1;
upsdebugx(3, "SSL connected");
break;
case 0:
upslog_with_errno(LOG_ERR, "SSL_accept do not accept handshake.");
ssl_error(client->ssl, ret);
break;
case -1:
upslog_with_errno(LOG_ERR, "Unknown return value from SSL_accept");
ssl_error(client->ssl, ret);
break;
}
#elif defined(WITH_NSS) /* WITH_OPENSSL */
socket = PR_ImportTCPSocket(client->sock_fd);
if (socket == NULL){
upslogx(LOG_ERR, "Can not inialize SSL connection");
nss_error("net_starttls / PR_ImportTCPSocket");
return;
}
client->ssl = SSL_ImportFD(NULL, socket);
if (client->ssl == NULL){
upslogx(LOG_ERR, "Can not inialize SSL connection");
nss_error("net_starttls / SSL_ImportFD");
return;
}
if (SSL_SetPKCS11PinArg(client->ssl, client) == -1){
upslogx(LOG_ERR, "Can not inialize SSL connection");
nss_error("net_starttls / SSL_SetPKCS11PinArg");
return;
}
/* Note cast to SSLAuthCertificate to prevent warning due to
* bad function prototype in NSS.
*/
status = SSL_AuthCertificateHook(client->ssl, (SSLAuthCertificate)AuthCertificate, CERT_GetDefaultCertDB());
if (status != SECSuccess) {
upslogx(LOG_ERR, "Can not inialize SSL connection");
nss_error("net_starttls / SSL_AuthCertificateHook");
return;
}
status = SSL_BadCertHook(client->ssl, (SSLBadCertHandler)BadCertHandler, client);
if (status != SECSuccess) {
upslogx(LOG_ERR, "Can not inialize SSL connection");
nss_error("net_starttls / SSL_BadCertHook");
return;
}
status = SSL_HandshakeCallback(client->ssl, (SSLHandshakeCallback)HandshakeCallback, client);
if (status != SECSuccess) {
upslogx(LOG_ERR, "Can not inialize SSL connection");
nss_error("net_starttls / SSL_HandshakeCallback");
return;
}
status = SSL_ConfigSecureServer(client->ssl, cert, privKey, NSS_FindCertKEAType(cert));
if (status != SECSuccess) {
upslogx(LOG_ERR, "Can not inialize SSL connection");
nss_error("net_starttls / SSL_ConfigSecureServer");
return;
}
status = SSL_ResetHandshake(client->ssl, PR_TRUE);
if (status != SECSuccess) {
upslogx(LOG_ERR, "Can not inialize SSL connection");
nss_error("net_starttls / SSL_ResetHandshake");
return;
}
/* Note: this call can generate memory leaks not resolvable
* by any release function.
* Probably SSL session key object allocation. */
status = SSL_ForceHandshake(client->ssl);
if (status != SECSuccess) {
PRErrorCode code = PR_GetError();
if (code==SSL_ERROR_NO_CERTIFICATE) {
upslogx(LOG_WARNING, "Client %s do not provide certificate.",
client->addr);
} else {
nss_error("net_starttls / SSL_ForceHandshake");
/* TODO : Close the connection. */
return;
}
}
client->ssl_connected = 1;
#endif /* WITH_OPENSSL | WITH_NSS */
}
void ssl_init(void)
{
#ifdef WITH_NSS
SECStatus status;
#elif defined(WITH_OPENSSL)
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
const SSL_METHOD *ssl_method;
#else
SSL_METHOD *ssl_method;
#endif
#endif /* WITH_NSS|WITH_OPENSSL */
if (!certfile) {
return;
}
check_perms(certfile);
#ifdef WITH_OPENSSL
SSL_load_error_strings();
SSL_library_init();
@ -162,60 +422,105 @@ void ssl_init(void)
SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_NONE, NULL);
ssl_initialized = 1;
}
static int ssl_error(SSL *ssl, int ret)
{
int e;
e = SSL_get_error(ssl, ret);
switch (e)
{
case SSL_ERROR_WANT_READ:
upsdebugx(1, "ssl_error() ret=%d SSL_ERROR_WANT_READ", ret);
break;
case SSL_ERROR_WANT_WRITE:
upsdebugx(1, "ssl_error() ret=%d SSL_ERROR_WANT_WRITE", ret);
break;
case SSL_ERROR_SYSCALL:
if (ret == 0 && ERR_peek_error() == 0) {
upsdebugx(1, "ssl_error() EOF from client");
} else {
upsdebugx(1, "ssl_error() ret=%d SSL_ERROR_SYSCALL", ret);
}
break;
default:
upsdebugx(1, "ssl_error() ret=%d SSL_ERROR %d", ret, e);
ssl_debug();
}
return -1;
}
static int ssl_accept(nut_ctype_t *client)
{
int ret;
ret = SSL_accept(client->ssl);
switch (ret)
{
case 1:
client->ssl_connected = 1;
upsdebugx(3, "SSL connected");
return 0;
case 0:
case -1:
return ssl_error(client->ssl, ret);
#elif defined(WITH_NSS) /* WITH_OPENSSL */
if (!certname || certname[0]==0 ) {
upslogx(LOG_ERR, "The SSL certificate name is not specified.");
return;
}
PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
PK11_SetPasswordFunc(nss_password_callback);
if (certfile)
/* Note: this call can generate memory leaks not resolvable
* by any release function.
* Probably NSS key module object allocation and
* probably NSS key db object allocation too. */
status = NSS_Init(certfile);
else
status = NSS_NoDB_Init(NULL);
if (status != SECSuccess) {
upslogx(LOG_ERR, "Can not initialize SSL context");
nss_error("upscli_init / NSS_[NoDB]_Init");
return;
}
upslog_with_errno(LOG_ERR, "Unknown return value from SSL_accept");
return -1;
status = NSS_SetDomesticPolicy();
if (status != SECSuccess) {
upslogx(LOG_ERR, "Can not initialize SSL policy");
nss_error("upscli_init / NSS_SetDomesticPolicy");
return;
}
/* Default server cache config */
status = SSL_ConfigServerSessionIDCache(0, 0, 0, NULL);
if (status != SECSuccess) {
upslogx(LOG_ERR, "Can not initialize SSL server cache");
nss_error("upscli_init / SSL_ConfigServerSessionIDCache");
return;
}
status = SSL_OptionSetDefault(SSL_ENABLE_SSL3, PR_TRUE);
if (status != SECSuccess) {
upslogx(LOG_ERR, "Can not enable SSLv3");
nss_error("upscli_init / SSL_OptionSetDefault(SSL_ENABLE_SSL3)");
return;
}
status = SSL_OptionSetDefault(SSL_ENABLE_TLS, PR_TRUE);
if (status != SECSuccess) {
upslogx(LOG_ERR, "Can not enable TLSv1");
nss_error("upscli_init / SSL_OptionSetDefault(SSL_ENABLE_TLS)");
return;
}
#ifdef WITH_CLIENT_CERTIFICATE_VALIDATION
if (certrequest < NETSSL_CERTREQ_NO &&
certrequest > NETSSL_CERTREQ_REQUEST) {
upslogx(LOG_ERR, "Invalid certificate requirement");
return;
}
if (certrequest == NETSSL_CERTREQ_REQUEST ||
certrequest == NETSSL_CERTREQ_REQUIRE ) {
status = SSL_OptionSetDefault(SSL_REQUEST_CERTIFICATE, PR_TRUE);
if (status != SECSuccess) {
upslogx(LOG_ERR, "Can not enable certificate request");
nss_error("upscli_init / SSL_OptionSetDefault(SSL_REQUEST_CERTIFICATE)");
return;
}
}
if (certrequest == NETSSL_CERTREQ_REQUIRE ) {
status = SSL_OptionSetDefault(SSL_REQUIRE_CERTIFICATE, PR_TRUE);
if (status != SECSuccess) {
upslogx(LOG_ERR, "Can not enable certificate requirement");
nss_error("upscli_init / SSL_OptionSetDefault(SSL_REQUIRE_CERTIFICATE)");
return;
}
}
#endif /* WITH_CLIENT_CERTIFICATE_VALIDATION */
cert = PK11_FindCertFromNickname(certname, NULL);
if(cert==NULL) {
upslogx(LOG_ERR, "Can not find server certificate");
nss_error("upscli_init / PK11_FindCertFromNickname");
return;
}
privKey = PK11_FindKeyByAnyCert(cert, NULL);
if(privKey==NULL){
upslogx(LOG_ERR, "Can not find private key associate to server certificate");
nss_error("upscli_init / PK11_FindKeyByAnyCert");
return;
}
ssl_initialized = 1;
#else /* WITH_OPENSSL | WITH_NSS */
upslogx(LOG_ERR, "ssl_init called but SSL wasn't compiled in");
#endif /* WITH_OPENSSL | WITH_NSS */
}
int ssl_read(nut_ctype_t *client, char *buf, size_t buflen)
@ -223,11 +528,14 @@ int ssl_read(nut_ctype_t *client, char *buf, size_t buflen)
int ret;
if (!client->ssl_connected) {
if (ssl_accept(client) != 0)
return -1;
return -1;
}
#ifdef WITH_OPENSSL
ret = SSL_read(client->ssl, buf, buflen);
#elif defined(WITH_NSS) /* WITH_OPENSSL */
ret = PR_Read(client->ssl, buf, buflen);
#endif /* WITH_OPENSSL | WITH_NSS */
if (ret < 1) {
ssl_error(client->ssl, ret);
@ -241,7 +549,15 @@ int ssl_write(nut_ctype_t *client, const char *buf, size_t buflen)
{
int ret;
if (!client->ssl_connected) {
return -1;
}
#ifdef WITH_OPENSSL
ret = SSL_write(client->ssl, buf, buflen);
#elif defined(WITH_NSS) /* WITH_OPENSSL */
ret = PR_Write(client->ssl, buf, buflen);
#endif /* WITH_OPENSSL | WITH_NSS */
upsdebugx(5, "ssl_write ret=%d", ret);
@ -251,8 +567,36 @@ int ssl_write(nut_ctype_t *client, const char *buf, size_t buflen)
void ssl_finish(nut_ctype_t *client)
{
if (client->ssl) {
#ifdef WITH_OPENSSL
SSL_free(client->ssl);
#elif defined(WITH_NSS)
PR_Shutdown(client->ssl, PR_SHUTDOWN_BOTH);
PR_Close(client->ssl);
#endif /* WITH_OPENSSL | WITH_NSS */
client->ssl_connected = 0;
client->ssl = NULL;
}
}
#endif /* HAVE_SSL */
void ssl_cleanup(void)
{
#ifdef WITH_OPENSSL
if (ssl_ctx) {
SSL_CTX_free(ssl_ctx);
ssl_ctx = NULL;
}
#elif defined(WITH_NSS) /* WITH_OPENSSL */
CERT_DestroyCertificate(cert);
SECKEY_DestroyPrivateKey(privKey);
NSS_Shutdown();
PR_Cleanup();
/* Called to release memory arena used by NSS/NSPR.
* Prevent to show all PL_ArenaAllocate mem alloc as leaks.
* https://developer.mozilla.org/en/NSS_Memory_allocation
*/
PL_ArenaFinish();
#endif /* WITH_OPENSSL | WITH_NSS */
ssl_initialized = 0;
}
#endif /* WITH_SSL */

View file

@ -17,24 +17,46 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef SSL_H_SEEN
#define SSL_H_SEEN 1
#ifdef HAVE_SSL
#include <openssl/err.h>
#include <openssl/ssl.h>
#endif
#ifndef NETSSL_H_SEEN
#define NETSSL_H_SEEN 1
#include "nut_ctype.h"
#ifdef __cplusplus
/* *INDENT-OFF* */
extern "C" {
/* *INDENT-ON* */
#endif
extern char *certfile;
extern char *certname;
extern char *certpasswd;
#ifdef WITH_CLIENT_CERTIFICATE_VALIDATION
extern int certrequest;
#endif /* WITH_CLIENT_CERTIFICATE_VALIDATION */
/* List possible values for certrequested */
/* No request */
#define NETSSL_CERTREQ_NO 0
/* Requested (cnx failed if no certificate) */
#define NETSSL_CERTREQ_REQUEST 1
/* Required (cnx failed if no certificate or invalid CA chain) */
#define NETSSL_CERTREQ_REQUIRE 2
void ssl_init(void);
void ssl_finish(nut_ctype_t *client);
void ssl_cleanup(void);
int ssl_read(nut_ctype_t *client, char *buf, size_t buflen);
int ssl_write(nut_ctype_t *client, const char *buf, size_t buflen);
void net_starttls(nut_ctype_t *client, int numarg, const char **arg);
#endif /* SSL_H_SEEN */
#ifdef __cplusplus
/* *INDENT-OFF* */
}
/* *INDENT-ON* */
#endif
#endif /* NETSSL_H_SEEN */

View file

@ -1,5 +1,18 @@
#ifdef __cplusplus
/* *INDENT-OFF* */
extern "C" {
/* *INDENT-ON* */
#endif
void net_login(nut_ctype_t *client, int numarg, const char **arg);
void net_logout(nut_ctype_t *client, int numarg, const char **arg);
void net_master(nut_ctype_t *client, int numarg, const char **arg);
void net_username(nut_ctype_t *client, int numarg, const char **arg);
void net_password(nut_ctype_t *client, int numarg, const char **arg);
#ifdef __cplusplus
/* *INDENT-OFF* */
}
/* *INDENT-ON* */
#endif

View file

@ -23,9 +23,16 @@
#ifndef NUT_CTYPE_H_SEEN
#define NUT_CTYPE_H_SEEN 1
#ifdef HAVE_SSL
#include <openssl/err.h>
#include <openssl/ssl.h>
/* Mozilla NSS */
#ifdef WITH_NSS
#include <nss.h>
#include <ssl.h>
#endif
/* OpenSSL */
#ifdef WITH_OPENSSL
#include <openssl/err.h>
#include <openssl/ssl.h>
#endif
#include "parseconf.h"
@ -39,10 +46,12 @@ typedef struct nut_ctype_s {
char *password;
char *username;
#ifdef HAVE_SSL
#ifdef WITH_OPENSSL
SSL *ssl;
#elif defined(WITH_NSS)
PRFileDesc *ssl;
#else
void *ssl;
void *ssl;
#endif
int ssl_connected;

View file

@ -29,6 +29,12 @@
#define SS_CONNFAIL_INT 300 /* complain about a dead driver every 5 mins */
#define SS_MAX_READ 256 /* don't let drivers tie us up in read() */
#ifdef __cplusplus
/* *INDENT-OFF* */
extern "C" {
/* *INDENT-ON* */
#endif
int sstate_connect(upstype_t *ups);
void sstate_disconnect(upstype_t *ups);
void sstate_readline(upstype_t *ups);
@ -47,4 +53,10 @@ void sstate_cmdfree(upstype_t *ups);
int sstate_sendline(upstype_t *ups, const char *buf);
const st_tree_t *sstate_getnode(const upstype_t *ups, const char *varname);
#ifdef __cplusplus
/* *INDENT-OFF* */
}
/* *INDENT-ON* */
#endif
#endif /* SSTATE_H_SEEN */

View file

@ -31,6 +31,12 @@
#define NI_MAXSERV 32
#endif
#ifdef __cplusplus
/* *INDENT-OFF* */
extern "C" {
/* *INDENT-ON* */
#endif
typedef struct stype_s {
char *addr;
char *port;
@ -38,4 +44,10 @@ typedef struct stype_s {
struct stype_s *next;
} stype_t;
#ifdef __cplusplus
/* *INDENT-OFF* */
}
/* *INDENT-ON* */
#endif
#endif /* STYPE_H_SEEN */

View file

@ -325,9 +325,12 @@ int sendback(nut_ctype_t *client, const char *fmt, ...)
len = strlen(ans);
#ifdef WITH_SSL
if (client->ssl) {
res = ssl_write(client, ans, len);
} else {
} else
#endif /* WITH_SSL */
{
res = write(client->sock_fd, ans, len);
}
@ -503,9 +506,12 @@ static void client_readline(nut_ctype_t *client)
char buf[SMALLBUF];
int i, ret;
#ifdef WITH_SSL
if (client->ssl) {
ret = ssl_read(client, buf, sizeof(buf));
} else {
} else
#endif /* WITH_SSL */
{
ret = read(client->sock_fd, buf, sizeof(buf));
}
@ -642,6 +648,8 @@ static void upsd_cleanup(void)
free(statepath);
free(datapath);
free(certfile);
free(certname);
free(certpasswd);
free(fds);
free(handler);
@ -1034,6 +1042,8 @@ int main(int argc, char **argv)
mainloop();
}
ssl_cleanup();
upslogx(LOG_INFO, "Signal %d: exiting", exit_flag);
return EXIT_SUCCESS;
}

View file

@ -45,6 +45,12 @@
#define NUT_NET_ANSWER_MAX SMALLBUF
#ifdef __cplusplus
/* *INDENT-OFF* */
extern "C" {
/* *INDENT-ON* */
#endif
/* prototypes from upsd.c */
upstype_t *get_ups_ptr(const char *upsname);
@ -85,4 +91,10 @@ extern nut_ctype_t *firstclient;
#define shutdown_how 2
#endif
#ifdef __cplusplus
/* *INDENT-OFF* */
}
/* *INDENT-ON* */
#endif
#endif /* UPSD_H_SEEN */

View file

@ -24,6 +24,12 @@
#include "parseconf.h"
#ifdef __cplusplus
/* *INDENT-OFF* */
extern "C" {
/* *INDENT-ON* */
#endif
/* structure for the linked list of each UPS that we track */
typedef struct upstype_s {
char *name;
@ -52,4 +58,10 @@ typedef struct upstype_s {
extern upstype_t *firstups;
#ifdef __cplusplus
/* *INDENT-OFF* */
}
/* *INDENT-ON* */
#endif
#endif /* UPSTYPE_H_SEEN */

View file

@ -17,6 +17,12 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef __cplusplus
/* *INDENT-OFF* */
extern "C" {
/* *INDENT-ON* */
#endif
typedef struct {
char *cmd;
void *next;
@ -34,3 +40,10 @@ typedef struct {
actionlist_t *firstaction;
void *next;
} ulist_t;
#ifdef __cplusplus
/* *INDENT-OFF* */
}
/* *INDENT-ON* */
#endif

View file

@ -17,6 +17,12 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef __cplusplus
/* *INDENT-OFF* */
extern "C" {
/* *INDENT-ON* */
#endif
void user_load(void);
int user_checkinstcmd(const char *un, const char *pw, const char *cmd);
@ -26,3 +32,10 @@ void user_flush(void);
/* cheat - we don't want the full upsd.h included here */
void check_perms(const char *fn);
#ifdef __cplusplus
/* *INDENT-OFF* */
}
/* *INDENT-ON* */
#endif