mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-23 16:20:26 -05:00
- patch for remote control over local sockets, from Dag-Erling
Smorgrav, Ilya Bakulin. Use control-interface: /path/sock and control-use-cert: no. git-svn-id: file:///svn/unbound/trunk@3304 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
0dea293963
commit
df73be98bd
20 changed files with 2011 additions and 1740 deletions
|
|
@ -353,6 +353,9 @@
|
||||||
/* Define to 1 if `ipi_spec_dst' is a member of `struct in_pktinfo'. */
|
/* Define to 1 if `ipi_spec_dst' is a member of `struct in_pktinfo'. */
|
||||||
#undef HAVE_STRUCT_IN_PKTINFO_IPI_SPEC_DST
|
#undef HAVE_STRUCT_IN_PKTINFO_IPI_SPEC_DST
|
||||||
|
|
||||||
|
/* Define to 1 if `sun_len' is a member of `struct sockaddr_un'. */
|
||||||
|
#undef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
|
||||||
|
|
||||||
/* Define if you have Swig libraries and header files. */
|
/* Define if you have Swig libraries and header files. */
|
||||||
#undef HAVE_SWIG
|
#undef HAVE_SWIG
|
||||||
|
|
||||||
|
|
@ -383,6 +386,9 @@
|
||||||
/* Define to 1 if you have the <sys/uio.h> header file. */
|
/* Define to 1 if you have the <sys/uio.h> header file. */
|
||||||
#undef HAVE_SYS_UIO_H
|
#undef HAVE_SYS_UIO_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/un.h> header file. */
|
||||||
|
#undef HAVE_SYS_UN_H
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/wait.h> header file. */
|
/* Define to 1 if you have the <sys/wait.h> header file. */
|
||||||
#undef HAVE_SYS_WAIT_H
|
#undef HAVE_SYS_WAIT_H
|
||||||
|
|
||||||
|
|
|
||||||
18
configure
vendored
18
configure
vendored
|
|
@ -13739,7 +13739,7 @@ CC="$lt_save_CC"
|
||||||
|
|
||||||
|
|
||||||
# Checks for header files.
|
# Checks for header files.
|
||||||
for ac_header in stdarg.h stdbool.h netinet/in.h sys/param.h sys/socket.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h
|
for ac_header in stdarg.h stdbool.h netinet/in.h sys/param.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h
|
||||||
do :
|
do :
|
||||||
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
|
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
|
||||||
ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
|
ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
|
||||||
|
|
@ -17844,6 +17844,22 @@ $as_echo "no" >&6; }
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
ac_fn_c_check_member "$LINENO" "struct sockaddr_un" "sun_len" "ac_cv_member_struct_sockaddr_un_sun_len" "
|
||||||
|
$ac_includes_default
|
||||||
|
#ifdef HAVE_SYS_UN_H
|
||||||
|
#include <sys/un.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
"
|
||||||
|
if test "x$ac_cv_member_struct_sockaddr_un_sun_len" = xyes; then :
|
||||||
|
|
||||||
|
cat >>confdefs.h <<_ACEOF
|
||||||
|
#define HAVE_STRUCT_SOCKADDR_UN_SUN_LEN 1
|
||||||
|
_ACEOF
|
||||||
|
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
ac_fn_c_check_member "$LINENO" "struct in_pktinfo" "ipi_spec_dst" "ac_cv_member_struct_in_pktinfo_ipi_spec_dst" "
|
ac_fn_c_check_member "$LINENO" "struct in_pktinfo" "ipi_spec_dst" "ac_cv_member_struct_in_pktinfo_ipi_spec_dst" "
|
||||||
|
|
|
||||||
|
|
@ -269,7 +269,7 @@ AC_CHECK_TOOL(STRIP, strip)
|
||||||
ACX_LIBTOOL_C_ONLY
|
ACX_LIBTOOL_C_ONLY
|
||||||
|
|
||||||
# Checks for header files.
|
# Checks for header files.
|
||||||
AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h sys/param.h sys/socket.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h],,, [AC_INCLUDES_DEFAULT])
|
AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h sys/param.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h],,, [AC_INCLUDES_DEFAULT])
|
||||||
|
|
||||||
# check for types.
|
# check for types.
|
||||||
# Using own tests for int64* because autoconf builtin only give 32bit.
|
# Using own tests for int64* because autoconf builtin only give 32bit.
|
||||||
|
|
@ -941,6 +941,12 @@ if test $ac_cv_func_daemon = yes; then
|
||||||
])
|
])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
AC_CHECK_MEMBERS([struct sockaddr_un.sun_len],,,[
|
||||||
|
AC_INCLUDES_DEFAULT
|
||||||
|
#ifdef HAVE_SYS_UN_H
|
||||||
|
#include <sys/un.h>
|
||||||
|
#endif
|
||||||
|
])
|
||||||
AC_CHECK_MEMBERS([struct in_pktinfo.ipi_spec_dst],,,[
|
AC_CHECK_MEMBERS([struct in_pktinfo.ipi_spec_dst],,,[
|
||||||
AC_INCLUDES_DEFAULT
|
AC_INCLUDES_DEFAULT
|
||||||
#if HAVE_SYS_PARAM_H
|
#if HAVE_SYS_PARAM_H
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,10 @@
|
||||||
#ifdef HAVE_OPENSSL_ERR_H
|
#ifdef HAVE_OPENSSL_ERR_H
|
||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef HEADER_DH_H
|
||||||
|
#include <openssl/dh.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include "daemon/remote.h"
|
#include "daemon/remote.h"
|
||||||
#include "daemon/worker.h"
|
#include "daemon/worker.h"
|
||||||
|
|
@ -82,6 +86,9 @@
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
# include <sys/types.h>
|
# include <sys/types.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_SYS_STAT_H
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#endif
|
||||||
#ifdef HAVE_NETDB_H
|
#ifdef HAVE_NETDB_H
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -131,6 +138,39 @@ timeval_divide(struct timeval* avg, const struct timeval* sum, size_t d)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following function was generated using the openssl utility, using
|
||||||
|
* the command : "openssl dhparam -dsaparam -C 512"
|
||||||
|
*/
|
||||||
|
DH *get_dh512()
|
||||||
|
{
|
||||||
|
static unsigned char dh512_p[]={
|
||||||
|
0xC9,0xD7,0x05,0xDA,0x5F,0xAB,0x14,0xE8,0x11,0x56,0x77,0x85,
|
||||||
|
0xB1,0x24,0x2C,0x95,0x60,0xEA,0xE2,0x10,0x6F,0x0F,0x84,0xEC,
|
||||||
|
0xF4,0x45,0xE8,0x90,0x7A,0xA7,0x03,0xFF,0x5B,0x88,0x53,0xDE,
|
||||||
|
0xC4,0xDE,0xBC,0x42,0x78,0x71,0x23,0x7E,0x24,0xA5,0x5E,0x4E,
|
||||||
|
0xEF,0x6F,0xFF,0x5F,0xAF,0xBE,0x8A,0x77,0x62,0xB4,0x65,0x82,
|
||||||
|
0x7E,0xC9,0xED,0x2F,
|
||||||
|
};
|
||||||
|
static unsigned char dh512_g[]={
|
||||||
|
0x8D,0x3A,0x52,0xBC,0x8A,0x71,0x94,0x33,0x2F,0xE1,0xE8,0x4C,
|
||||||
|
0x73,0x47,0x03,0x4E,0x7D,0x40,0xE5,0x84,0xA0,0xB5,0x6D,0x10,
|
||||||
|
0x6F,0x90,0x43,0x05,0x1A,0xF9,0x0B,0x6A,0xD1,0x2A,0x9C,0x25,
|
||||||
|
0x0A,0xB9,0xD1,0x14,0xDC,0x35,0x1C,0x48,0x7C,0xC6,0x0C,0x6D,
|
||||||
|
0x32,0x1D,0xD3,0xC8,0x10,0xA8,0x82,0x14,0xA2,0x1C,0xF4,0x53,
|
||||||
|
0x23,0x3B,0x1C,0xB9,
|
||||||
|
};
|
||||||
|
DH *dh;
|
||||||
|
|
||||||
|
if ((dh=DH_new()) == NULL) return(NULL);
|
||||||
|
dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL);
|
||||||
|
dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL);
|
||||||
|
if ((dh->p == NULL) || (dh->g == NULL))
|
||||||
|
{ DH_free(dh); return(NULL); }
|
||||||
|
dh->length = 160;
|
||||||
|
return(dh);
|
||||||
|
}
|
||||||
|
|
||||||
struct daemon_remote*
|
struct daemon_remote*
|
||||||
daemon_remote_create(struct config_file* cfg)
|
daemon_remote_create(struct config_file* cfg)
|
||||||
{
|
{
|
||||||
|
|
@ -165,6 +205,24 @@ daemon_remote_create(struct config_file* cfg)
|
||||||
daemon_remote_delete(rc);
|
daemon_remote_delete(rc);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cfg->remote_control_use_cert == 0) {
|
||||||
|
/* No certificates are requested */
|
||||||
|
if(!SSL_CTX_set_cipher_list(rc->ctx, "aNULL")) {
|
||||||
|
log_crypto_err("Failed to set aNULL cipher list");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Since we have no certificates and hence no source of
|
||||||
|
* DH params, let's generate and set them
|
||||||
|
*/
|
||||||
|
if(!SSL_CTX_set_tmp_dh(rc->ctx,get_dh512())) {
|
||||||
|
log_crypto_err("Wanted to set DH param, but failed");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
rc->use_cert = 1;
|
||||||
s_cert = fname_after_chroot(cfg->server_cert_file, cfg, 1);
|
s_cert = fname_after_chroot(cfg->server_cert_file, cfg, 1);
|
||||||
s_key = fname_after_chroot(cfg->server_key_file, cfg, 1);
|
s_key = fname_after_chroot(cfg->server_key_file, cfg, 1);
|
||||||
if(!s_cert || !s_key) {
|
if(!s_cert || !s_key) {
|
||||||
|
|
@ -244,7 +302,8 @@ void daemon_remote_delete(struct daemon_remote* rc)
|
||||||
* @return false on failure.
|
* @return false on failure.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
add_open(const char* ip, int nr, struct listen_port** list, int noproto_is_err)
|
add_open(const char* ip, int nr, struct listen_port** list, int noproto_is_err,
|
||||||
|
struct config_file* cfg)
|
||||||
{
|
{
|
||||||
struct addrinfo hints;
|
struct addrinfo hints;
|
||||||
struct addrinfo* res;
|
struct addrinfo* res;
|
||||||
|
|
@ -255,6 +314,21 @@ add_open(const char* ip, int nr, struct listen_port** list, int noproto_is_err)
|
||||||
snprintf(port, sizeof(port), "%d", nr);
|
snprintf(port, sizeof(port), "%d", nr);
|
||||||
port[sizeof(port)-1]=0;
|
port[sizeof(port)-1]=0;
|
||||||
memset(&hints, 0, sizeof(hints));
|
memset(&hints, 0, sizeof(hints));
|
||||||
|
|
||||||
|
if(ip[0] == '/') {
|
||||||
|
/* This looks like a local socket */
|
||||||
|
fd = create_local_accept_sock(ip, &noproto);
|
||||||
|
/*
|
||||||
|
* Change socket ownership and permissions so users other
|
||||||
|
* than root can access it provided they are in the same
|
||||||
|
* group as the user we run as.
|
||||||
|
*/
|
||||||
|
if(fd != -1) {
|
||||||
|
if (cfg->username && cfg->username[0])
|
||||||
|
chown(ip, cfg->uid, cfg->gid);
|
||||||
|
chmod(ip, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
|
hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
|
||||||
if((r = getaddrinfo(ip, port, &hints, &res)) != 0 || !res) {
|
if((r = getaddrinfo(ip, port, &hints, &res)) != 0 || !res) {
|
||||||
|
|
@ -278,6 +352,8 @@ add_open(const char* ip, int nr, struct listen_port** list, int noproto_is_err)
|
||||||
/* open fd */
|
/* open fd */
|
||||||
fd = create_tcp_accept_sock(res, 1, &noproto, 0);
|
fd = create_tcp_accept_sock(res, 1, &noproto, 0);
|
||||||
freeaddrinfo(res);
|
freeaddrinfo(res);
|
||||||
|
}
|
||||||
|
|
||||||
if(fd == -1 && noproto) {
|
if(fd == -1 && noproto) {
|
||||||
if(!noproto_is_err)
|
if(!noproto_is_err)
|
||||||
return 1; /* return success, but do nothing */
|
return 1; /* return success, but do nothing */
|
||||||
|
|
@ -314,7 +390,7 @@ struct listen_port* daemon_remote_open_ports(struct config_file* cfg)
|
||||||
if(cfg->control_ifs) {
|
if(cfg->control_ifs) {
|
||||||
struct config_strlist* p;
|
struct config_strlist* p;
|
||||||
for(p = cfg->control_ifs; p; p = p->next) {
|
for(p = cfg->control_ifs; p; p = p->next) {
|
||||||
if(!add_open(p->str, cfg->control_port, &l, 1)) {
|
if(!add_open(p->str, cfg->control_port, &l, 1, cfg)) {
|
||||||
listening_ports_free(l);
|
listening_ports_free(l);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -322,12 +398,12 @@ struct listen_port* daemon_remote_open_ports(struct config_file* cfg)
|
||||||
} else {
|
} else {
|
||||||
/* defaults */
|
/* defaults */
|
||||||
if(cfg->do_ip6 &&
|
if(cfg->do_ip6 &&
|
||||||
!add_open("::1", cfg->control_port, &l, 0)) {
|
!add_open("::1", cfg->control_port, &l, 0, cfg)) {
|
||||||
listening_ports_free(l);
|
listening_ports_free(l);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if(cfg->do_ip4 &&
|
if(cfg->do_ip4 &&
|
||||||
!add_open("127.0.0.1", cfg->control_port, &l, 1)) {
|
!add_open("127.0.0.1", cfg->control_port, &l, 1, cfg)) {
|
||||||
listening_ports_free(l);
|
listening_ports_free(l);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -2434,7 +2510,9 @@ int remote_control_callback(struct comm_point* c, void* arg, int err,
|
||||||
s->shake_state = rc_none;
|
s->shake_state = rc_none;
|
||||||
|
|
||||||
/* once handshake has completed, check authentication */
|
/* once handshake has completed, check authentication */
|
||||||
if(SSL_get_verify_result(s->ssl) == X509_V_OK) {
|
if (!rc->use_cert) {
|
||||||
|
verbose(VERB_ALGO, "unauthenticated remote control connection");
|
||||||
|
} else if(SSL_get_verify_result(s->ssl) == X509_V_OK) {
|
||||||
X509* x = SSL_get_peer_certificate(s->ssl);
|
X509* x = SSL_get_peer_certificate(s->ssl);
|
||||||
if(!x) {
|
if(!x) {
|
||||||
verbose(VERB_DETAIL, "remote control connection "
|
verbose(VERB_DETAIL, "remote control connection "
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,8 @@ struct daemon_remote {
|
||||||
struct worker* worker;
|
struct worker* worker;
|
||||||
/** commpoints for accepting remote control connections */
|
/** commpoints for accepting remote control connections */
|
||||||
struct listen_list* accept_list;
|
struct listen_list* accept_list;
|
||||||
|
/* if certificates are used */
|
||||||
|
int use_cert;
|
||||||
/** number of active commpoints that are handling remote control */
|
/** number of active commpoints that are handling remote control */
|
||||||
int active;
|
int active;
|
||||||
/** max active commpoints */
|
/** max active commpoints */
|
||||||
|
|
|
||||||
|
|
@ -443,18 +443,10 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
|
||||||
{
|
{
|
||||||
#ifdef HAVE_GETPWNAM
|
#ifdef HAVE_GETPWNAM
|
||||||
struct passwd *pwd = NULL;
|
struct passwd *pwd = NULL;
|
||||||
uid_t uid;
|
|
||||||
gid_t gid;
|
|
||||||
/* initialize, but not to 0 (root) */
|
|
||||||
memset(&uid, 112, sizeof(uid));
|
|
||||||
memset(&gid, 112, sizeof(gid));
|
|
||||||
log_assert(cfg);
|
|
||||||
|
|
||||||
if(cfg->username && cfg->username[0]) {
|
if(cfg->username && cfg->username[0]) {
|
||||||
if((pwd = getpwnam(cfg->username)) == NULL)
|
if((pwd = getpwnam(cfg->username)) == NULL)
|
||||||
fatal_exit("user '%s' does not exist.", cfg->username);
|
fatal_exit("user '%s' does not exist.", cfg->username);
|
||||||
uid = pwd->pw_uid;
|
|
||||||
gid = pwd->pw_gid;
|
|
||||||
/* endpwent below, in case we need pwd for setusercontext */
|
/* endpwent below, in case we need pwd for setusercontext */
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -511,21 +503,14 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
|
||||||
#ifdef HAVE_KILL
|
#ifdef HAVE_KILL
|
||||||
if(cfg->pidfile && cfg->pidfile[0]) {
|
if(cfg->pidfile && cfg->pidfile[0]) {
|
||||||
writepid(daemon->pidfile, getpid());
|
writepid(daemon->pidfile, getpid());
|
||||||
if(!(cfg->chrootdir && cfg->chrootdir[0]) ||
|
|
||||||
(cfg->chrootdir && cfg->chrootdir[0] &&
|
|
||||||
strncmp(daemon->pidfile, cfg->chrootdir,
|
|
||||||
strlen(cfg->chrootdir))==0)) {
|
|
||||||
/* delete of pidfile could potentially work,
|
|
||||||
* chown to get permissions */
|
|
||||||
if(cfg->username && cfg->username[0]) {
|
if(cfg->username && cfg->username[0]) {
|
||||||
if(chown(daemon->pidfile, uid, gid) == -1) {
|
if(chown(daemon->pidfile, cfg->uid, cfg->gid) == -1) {
|
||||||
log_err("cannot chown %u.%u %s: %s",
|
log_err("cannot chown %u.%u %s: %s",
|
||||||
(unsigned)uid, (unsigned)gid,
|
(unsigned)cfg->uid, (unsigned)cfg->gid,
|
||||||
daemon->pidfile, strerror(errno));
|
daemon->pidfile, strerror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
(void)daemon;
|
(void)daemon;
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -537,7 +522,7 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
|
||||||
/* setusercontext does initgroups, setuid, setgid, and
|
/* setusercontext does initgroups, setuid, setgid, and
|
||||||
* also resource limits from login config, but we
|
* also resource limits from login config, but we
|
||||||
* still call setresuid, setresgid to be sure to set all uid*/
|
* still call setresuid, setresgid to be sure to set all uid*/
|
||||||
if(setusercontext(NULL, pwd, uid, (unsigned)
|
if(setusercontext(NULL, pwd, cfg->uid, (unsigned)
|
||||||
LOGIN_SETALL & ~LOGIN_SETUSER & ~LOGIN_SETGROUP) != 0)
|
LOGIN_SETALL & ~LOGIN_SETUSER & ~LOGIN_SETGROUP) != 0)
|
||||||
log_warn("unable to setusercontext %s: %s",
|
log_warn("unable to setusercontext %s: %s",
|
||||||
cfg->username, strerror(errno));
|
cfg->username, strerror(errno));
|
||||||
|
|
@ -601,27 +586,27 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
|
||||||
#ifdef HAVE_GETPWNAM
|
#ifdef HAVE_GETPWNAM
|
||||||
if(cfg->username && cfg->username[0]) {
|
if(cfg->username && cfg->username[0]) {
|
||||||
# ifdef HAVE_INITGROUPS
|
# ifdef HAVE_INITGROUPS
|
||||||
if(initgroups(cfg->username, gid) != 0)
|
if(initgroups(cfg->username, cfg->gid) != 0)
|
||||||
log_warn("unable to initgroups %s: %s",
|
log_warn("unable to initgroups %s: %s",
|
||||||
cfg->username, strerror(errno));
|
cfg->username, strerror(errno));
|
||||||
# endif /* HAVE_INITGROUPS */
|
# endif /* HAVE_INITGROUPS */
|
||||||
endpwent();
|
endpwent();
|
||||||
|
|
||||||
#ifdef HAVE_SETRESGID
|
#ifdef HAVE_SETRESGID
|
||||||
if(setresgid(gid,gid,gid) != 0)
|
if(setresgid(cfg->gid,cfg->gid,cfg->gid) != 0)
|
||||||
#elif defined(HAVE_SETREGID) && !defined(DARWIN_BROKEN_SETREUID)
|
#elif defined(HAVE_SETREGID) && !defined(DARWIN_BROKEN_SETREUID)
|
||||||
if(setregid(gid,gid) != 0)
|
if(setregid(cfg->gid,cfg->gid) != 0)
|
||||||
#else /* use setgid */
|
#else /* use setgid */
|
||||||
if(setgid(gid) != 0)
|
if(setgid(cfg->gid) != 0)
|
||||||
#endif /* HAVE_SETRESGID */
|
#endif /* HAVE_SETRESGID */
|
||||||
fatal_exit("unable to set group id of %s: %s",
|
fatal_exit("unable to set group id of %s: %s",
|
||||||
cfg->username, strerror(errno));
|
cfg->username, strerror(errno));
|
||||||
#ifdef HAVE_SETRESUID
|
#ifdef HAVE_SETRESUID
|
||||||
if(setresuid(uid,uid,uid) != 0)
|
if(setresuid(cfg->uid,cfg->uid,cfg->uid) != 0)
|
||||||
#elif defined(HAVE_SETREUID) && !defined(DARWIN_BROKEN_SETREUID)
|
#elif defined(HAVE_SETREUID) && !defined(DARWIN_BROKEN_SETREUID)
|
||||||
if(setreuid(uid,uid) != 0)
|
if(setreuid(cfg->uid,cfg->uid) != 0)
|
||||||
#else /* use setuid */
|
#else /* use setuid */
|
||||||
if(setuid(uid) != 0)
|
if(setuid(cfg->uid) != 0)
|
||||||
#endif /* HAVE_SETRESUID */
|
#endif /* HAVE_SETRESUID */
|
||||||
fatal_exit("unable to set user id of %s: %s",
|
fatal_exit("unable to set user id of %s: %s",
|
||||||
cfg->username, strerror(errno));
|
cfg->username, strerror(errno));
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
6 January 2015: Wouter
|
6 January 2015: Wouter
|
||||||
- iana portlist update.
|
- iana portlist update.
|
||||||
|
- patch for remote control over local sockets, from Dag-Erling
|
||||||
|
Smorgrav, Ilya Bakulin. Use control-interface: /path/sock and
|
||||||
|
control-use-cert: no.
|
||||||
|
|
||||||
5 January 2015: Wouter
|
5 January 2015: Wouter
|
||||||
- getauxval test for ppc64 linux compatibility.
|
- getauxval test for ppc64 linux compatibility.
|
||||||
|
|
|
||||||
|
|
@ -969,32 +969,43 @@ section for options. To setup the correct self\-signed certificates use the
|
||||||
The option is used to enable remote control, default is "no".
|
The option is used to enable remote control, default is "no".
|
||||||
If turned off, the server does not listen for control commands.
|
If turned off, the server does not listen for control commands.
|
||||||
.TP 5
|
.TP 5
|
||||||
.B control\-interface: <ip address>
|
.B control\-interface: \fI<ip address or path>
|
||||||
Give IPv4 or IPv6 addresses to listen on for control commands.
|
Give IPv4 or IPv6 addresses or local socket path to listen on for
|
||||||
|
control commands.
|
||||||
By default localhost (127.0.0.1 and ::1) is listened to.
|
By default localhost (127.0.0.1 and ::1) is listened to.
|
||||||
Use 0.0.0.0 and ::0 to listen to all interfaces.
|
Use 0.0.0.0 and ::0 to listen to all interfaces.
|
||||||
|
If you change this and permissions have been dropped, you must restart
|
||||||
|
the server for the change to take effect.
|
||||||
.TP 5
|
.TP 5
|
||||||
.B control\-port: <port number>
|
.B control\-port: \fI<port number>
|
||||||
The port number to listen on for control commands, default is 8953.
|
The port number to listen on for IPv4 or IPv6 control interfaces,
|
||||||
If you change this port number, and permissions have been dropped,
|
default is 8953.
|
||||||
a reload is not sufficient to open the port again, you must then restart.
|
If you change this and permissions have been dropped, you must restart
|
||||||
|
the server for the change to take effect.
|
||||||
.TP 5
|
.TP 5
|
||||||
.B server\-key\-file: "<private key file>"
|
.B control\-use\-cert: \fI<yes or no>
|
||||||
|
Whether to require certificate authentication of control connections.
|
||||||
|
The default is "yes".
|
||||||
|
This should not be changed unless there are other mechanisms in place
|
||||||
|
to prevent untrusted users from accessing the remote control
|
||||||
|
interface.
|
||||||
|
.TP 5
|
||||||
|
.B server\-key\-file: \fI<private key file>
|
||||||
Path to the server private key, by default unbound_server.key.
|
Path to the server private key, by default unbound_server.key.
|
||||||
This file is generated by the \fIunbound\-control\-setup\fR utility.
|
This file is generated by the \fIunbound\-control\-setup\fR utility.
|
||||||
This file is used by the unbound server, but not by \fIunbound\-control\fR.
|
This file is used by the unbound server, but not by \fIunbound\-control\fR.
|
||||||
.TP 5
|
.TP 5
|
||||||
.B server\-cert\-file: "<certificate file.pem>"
|
.B server\-cert\-file: \fI<certificate file.pem>
|
||||||
Path to the server self signed certificate, by default unbound_server.pem.
|
Path to the server self signed certificate, by default unbound_server.pem.
|
||||||
This file is generated by the \fIunbound\-control\-setup\fR utility.
|
This file is generated by the \fIunbound\-control\-setup\fR utility.
|
||||||
This file is used by the unbound server, and also by \fIunbound\-control\fR.
|
This file is used by the unbound server, and also by \fIunbound\-control\fR.
|
||||||
.TP 5
|
.TP 5
|
||||||
.B control\-key\-file: "<private key file>"
|
.B control\-key\-file: \fI<private key file>
|
||||||
Path to the control client private key, by default unbound_control.key.
|
Path to the control client private key, by default unbound_control.key.
|
||||||
This file is generated by the \fIunbound\-control\-setup\fR utility.
|
This file is generated by the \fIunbound\-control\-setup\fR utility.
|
||||||
This file is used by \fIunbound\-control\fR.
|
This file is used by \fIunbound\-control\fR.
|
||||||
.TP 5
|
.TP 5
|
||||||
.B control\-cert\-file: "<certificate file.pem>"
|
.B control\-cert\-file: \fI<certificate file.pem>
|
||||||
Path to the control client certificate, by default unbound_control.pem.
|
Path to the control client certificate, by default unbound_control.pem.
|
||||||
This certificate has to be signed with the server certificate.
|
This certificate has to be signed with the server certificate.
|
||||||
This file is generated by the \fIunbound\-control\-setup\fR utility.
|
This file is generated by the \fIunbound\-control\-setup\fR utility.
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,10 @@
|
||||||
#endif
|
#endif
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_SYS_UN_H
|
||||||
|
#include <sys/un.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/** number of queued TCP connections for listen() */
|
/** number of queued TCP connections for listen() */
|
||||||
#define TCP_BACKLOG 256
|
#define TCP_BACKLOG 256
|
||||||
|
|
||||||
|
|
@ -589,6 +593,61 @@ create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
create_local_accept_sock(const char *path, int* noproto)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_SYS_UN_H
|
||||||
|
int s;
|
||||||
|
struct sockaddr_un sun;
|
||||||
|
|
||||||
|
#ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
|
||||||
|
/* this member exists on BSDs, not Linux */
|
||||||
|
sun.sun_len = sizeof(sun);
|
||||||
|
#endif
|
||||||
|
sun.sun_family = AF_LOCAL;
|
||||||
|
/* length is 92-108, 104 on FreeBSD */
|
||||||
|
strlcpy(sun.sun_path, path, sizeof(sun.sun_path));
|
||||||
|
|
||||||
|
if ((s = socket(PF_LOCAL, SOCK_STREAM, 0)) == -1) {
|
||||||
|
log_err("Cannot create local socket %s (%s)",
|
||||||
|
path, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unlink(path) && errno != ENOENT) {
|
||||||
|
/* The socket already exists and cannot be removed */
|
||||||
|
log_err("Cannot remove old local socket %s (%s)",
|
||||||
|
path, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bind(s, (struct sockaddr *)&sun,
|
||||||
|
sizeof(struct sockaddr_un)) == -1) {
|
||||||
|
log_err("Cannot bind local socket %s (%s)",
|
||||||
|
path, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fd_set_nonblock(s)) {
|
||||||
|
log_err("Cannot set non-blocking mode");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (listen(s, TCP_BACKLOG) == -1) {
|
||||||
|
log_err("can't listen: %s", strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)noproto; /*unused*/
|
||||||
|
return s;
|
||||||
|
#else
|
||||||
|
log_err("Local sockets are not supported");
|
||||||
|
*noproto = 1;
|
||||||
|
return -1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create socket from getaddrinfo results
|
* Create socket from getaddrinfo results
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -207,4 +207,13 @@ int create_udp_sock(int family, int socktype, struct sockaddr* addr,
|
||||||
int create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
|
int create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
|
||||||
int* reuseport);
|
int* reuseport);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create and bind local listening socket
|
||||||
|
* @param path: path to the socket.
|
||||||
|
* @param noproto: on error, this is set true if cause is that local sockets
|
||||||
|
* are not supported.
|
||||||
|
* @return: the socket. -1 on error.
|
||||||
|
*/
|
||||||
|
int create_local_accept_sock(const char* path, int* noproto);
|
||||||
|
|
||||||
#endif /* LISTEN_DNSPORT_H */
|
#endif /* LISTEN_DNSPORT_H */
|
||||||
|
|
|
||||||
|
|
@ -416,7 +416,7 @@ morechecks(struct config_file* cfg, const char* fname)
|
||||||
endpwent();
|
endpwent();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if(cfg->remote_control_enable) {
|
if(cfg->remote_control_enable && cfg->remote_control_use_cert) {
|
||||||
check_chroot_string("server-key-file", &cfg->server_key_file,
|
check_chroot_string("server-key-file", &cfg->server_key_file,
|
||||||
cfg->chrootdir, cfg);
|
cfg->chrootdir, cfg);
|
||||||
check_chroot_string("server-cert-file", &cfg->server_cert_file,
|
check_chroot_string("server-cert-file", &cfg->server_cert_file,
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,10 @@
|
||||||
#include "util/locks.h"
|
#include "util/locks.h"
|
||||||
#include "util/net_help.h"
|
#include "util/net_help.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_SYS_UN_H
|
||||||
|
#include <sys/un.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/** Give unbound-control usage, and exit (1). */
|
/** Give unbound-control usage, and exit (1). */
|
||||||
static void
|
static void
|
||||||
usage()
|
usage()
|
||||||
|
|
@ -136,19 +140,22 @@ static void ssl_err(const char* s)
|
||||||
static SSL_CTX*
|
static SSL_CTX*
|
||||||
setup_ctx(struct config_file* cfg)
|
setup_ctx(struct config_file* cfg)
|
||||||
{
|
{
|
||||||
char* s_cert, *c_key, *c_cert;
|
char* s_cert=NULL, *c_key=NULL, *c_cert=NULL;
|
||||||
SSL_CTX* ctx;
|
SSL_CTX* ctx;
|
||||||
|
|
||||||
|
if(cfg->remote_control_use_cert) {
|
||||||
s_cert = fname_after_chroot(cfg->server_cert_file, cfg, 1);
|
s_cert = fname_after_chroot(cfg->server_cert_file, cfg, 1);
|
||||||
c_key = fname_after_chroot(cfg->control_key_file, cfg, 1);
|
c_key = fname_after_chroot(cfg->control_key_file, cfg, 1);
|
||||||
c_cert = fname_after_chroot(cfg->control_cert_file, cfg, 1);
|
c_cert = fname_after_chroot(cfg->control_cert_file, cfg, 1);
|
||||||
if(!s_cert || !c_key || !c_cert)
|
if(!s_cert || !c_key || !c_cert)
|
||||||
fatal_exit("out of memory");
|
fatal_exit("out of memory");
|
||||||
|
}
|
||||||
ctx = SSL_CTX_new(SSLv23_client_method());
|
ctx = SSL_CTX_new(SSLv23_client_method());
|
||||||
if(!ctx)
|
if(!ctx)
|
||||||
ssl_err("could not allocate SSL_CTX pointer");
|
ssl_err("could not allocate SSL_CTX pointer");
|
||||||
if(!(SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2))
|
if(!(SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2))
|
||||||
ssl_err("could not set SSL_OP_NO_SSLv2");
|
ssl_err("could not set SSL_OP_NO_SSLv2");
|
||||||
|
if(cfg->remote_control_use_cert) {
|
||||||
if(!(SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3))
|
if(!(SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3))
|
||||||
ssl_err("could not set SSL_OP_NO_SSLv3");
|
ssl_err("could not set SSL_OP_NO_SSLv3");
|
||||||
if(!SSL_CTX_use_certificate_file(ctx,c_cert,SSL_FILETYPE_PEM) ||
|
if(!SSL_CTX_use_certificate_file(ctx,c_cert,SSL_FILETYPE_PEM) ||
|
||||||
|
|
@ -162,6 +169,11 @@ setup_ctx(struct config_file* cfg)
|
||||||
free(s_cert);
|
free(s_cert);
|
||||||
free(c_key);
|
free(c_key);
|
||||||
free(c_cert);
|
free(c_cert);
|
||||||
|
} else {
|
||||||
|
/* Use ciphers that don't require authentication */
|
||||||
|
if(!SSL_CTX_set_cipher_list(ctx, "aNULL"))
|
||||||
|
ssl_err("Error setting NULL cipher!");
|
||||||
|
}
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -171,6 +183,7 @@ contact_server(const char* svr, struct config_file* cfg, int statuscmd)
|
||||||
{
|
{
|
||||||
struct sockaddr_storage addr;
|
struct sockaddr_storage addr;
|
||||||
socklen_t addrlen;
|
socklen_t addrlen;
|
||||||
|
int addrfamily = 0;
|
||||||
int fd;
|
int fd;
|
||||||
/* use svr or the first config entry */
|
/* use svr or the first config entry */
|
||||||
if(!svr) {
|
if(!svr) {
|
||||||
|
|
@ -189,12 +202,25 @@ contact_server(const char* svr, struct config_file* cfg, int statuscmd)
|
||||||
if(strchr(svr, '@')) {
|
if(strchr(svr, '@')) {
|
||||||
if(!extstrtoaddr(svr, &addr, &addrlen))
|
if(!extstrtoaddr(svr, &addr, &addrlen))
|
||||||
fatal_exit("could not parse IP@port: %s", svr);
|
fatal_exit("could not parse IP@port: %s", svr);
|
||||||
|
#ifdef HAVE_SYS_UN_H
|
||||||
|
} else if(svr[0] == '/') {
|
||||||
|
struct sockaddr_un* sun = (struct sockaddr_un *) &addr;
|
||||||
|
sun->sun_family = AF_LOCAL;
|
||||||
|
#ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
|
||||||
|
sun->sun_len = sizeof(sun);
|
||||||
|
#endif
|
||||||
|
strlcpy(sun->sun_path, svr, sizeof(sun->sun_path));
|
||||||
|
addrlen = sizeof(struct sockaddr_un);
|
||||||
|
addrfamily = AF_LOCAL;
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
if(!ipstrtoaddr(svr, cfg->control_port, &addr, &addrlen))
|
if(!ipstrtoaddr(svr, cfg->control_port, &addr, &addrlen))
|
||||||
fatal_exit("could not parse IP: %s", svr);
|
fatal_exit("could not parse IP: %s", svr);
|
||||||
}
|
}
|
||||||
fd = socket(addr_is_ip6(&addr, addrlen)?AF_INET6:AF_INET,
|
|
||||||
SOCK_STREAM, 0);
|
if(addrfamily == 0)
|
||||||
|
addrfamily = addr_is_ip6(&addr, addrlen)?AF_INET6:AF_INET;
|
||||||
|
fd = socket(addrfamily, SOCK_STREAM, 0);
|
||||||
if(fd == -1) {
|
if(fd == -1) {
|
||||||
#ifndef USE_WINSOCK
|
#ifndef USE_WINSOCK
|
||||||
fatal_exit("socket: %s", strerror(errno));
|
fatal_exit("socket: %s", strerror(errno));
|
||||||
|
|
@ -223,7 +249,7 @@ contact_server(const char* svr, struct config_file* cfg, int statuscmd)
|
||||||
|
|
||||||
/** setup SSL on the connection */
|
/** setup SSL on the connection */
|
||||||
static SSL*
|
static SSL*
|
||||||
setup_ssl(SSL_CTX* ctx, int fd)
|
setup_ssl(SSL_CTX* ctx, int fd, struct config_file* cfg)
|
||||||
{
|
{
|
||||||
SSL* ssl;
|
SSL* ssl;
|
||||||
X509* x;
|
X509* x;
|
||||||
|
|
@ -249,10 +275,13 @@ setup_ssl(SSL_CTX* ctx, int fd)
|
||||||
/* check authenticity of server */
|
/* check authenticity of server */
|
||||||
if(SSL_get_verify_result(ssl) != X509_V_OK)
|
if(SSL_get_verify_result(ssl) != X509_V_OK)
|
||||||
ssl_err("SSL verification failed");
|
ssl_err("SSL verification failed");
|
||||||
|
if(cfg->remote_control_use_cert) {
|
||||||
x = SSL_get_peer_certificate(ssl);
|
x = SSL_get_peer_certificate(ssl);
|
||||||
if(!x)
|
if(!x)
|
||||||
ssl_err("Server presented no peer certificate");
|
ssl_err("Server presented no peer certificate");
|
||||||
X509_free(x);
|
X509_free(x);
|
||||||
|
}
|
||||||
|
|
||||||
return ssl;
|
return ssl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -333,7 +362,7 @@ go(const char* cfgfile, char* svr, int quiet, int argc, char* argv[])
|
||||||
|
|
||||||
/* contact server */
|
/* contact server */
|
||||||
fd = contact_server(svr, cfg, argc>0&&strcmp(argv[0],"status")==0);
|
fd = contact_server(svr, cfg, argc>0&&strcmp(argv[0],"status")==0);
|
||||||
ssl = setup_ssl(ctx, fd);
|
ssl = setup_ssl(ctx, fd, cfg);
|
||||||
|
|
||||||
/* send command */
|
/* send command */
|
||||||
ret = go_cmd(ssl, quiet, argc, argv);
|
ret = go_cmd(ssl, quiet, argc, argv);
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,9 @@
|
||||||
#ifdef HAVE_GLOB_H
|
#ifdef HAVE_GLOB_H
|
||||||
# include <glob.h>
|
# include <glob.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_PWD_H
|
||||||
|
#include <pwd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/** global config during parsing */
|
/** global config during parsing */
|
||||||
struct config_parser_state* cfg_parser = 0;
|
struct config_parser_state* cfg_parser = 0;
|
||||||
|
|
@ -131,6 +134,8 @@ config_create(void)
|
||||||
goto error_exit;
|
goto error_exit;
|
||||||
init_outgoing_availports(cfg->outgoing_avail_ports, 65536);
|
init_outgoing_availports(cfg->outgoing_avail_ports, 65536);
|
||||||
if(!(cfg->username = strdup(UB_USERNAME))) goto error_exit;
|
if(!(cfg->username = strdup(UB_USERNAME))) goto error_exit;
|
||||||
|
cfg->uid = (uid_t)-1;
|
||||||
|
cfg->gid = (gid_t)-1;
|
||||||
#ifdef HAVE_CHROOT
|
#ifdef HAVE_CHROOT
|
||||||
if(!(cfg->chrootdir = strdup(CHROOT_DIR))) goto error_exit;
|
if(!(cfg->chrootdir = strdup(CHROOT_DIR))) goto error_exit;
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -799,6 +804,17 @@ config_read(struct config_file* cfg, const char* filename, const char* chroot)
|
||||||
errno=EINVAL;
|
errno=EINVAL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_GETPWNAM
|
||||||
|
/* translate username into uid and gid */
|
||||||
|
if(cfg->username && cfg->username[0]) {
|
||||||
|
struct passwd *pwd;
|
||||||
|
if((pwd = getpwnam(cfg->username)) == NULL)
|
||||||
|
log_err("user '%s' does not exist.", cfg->username);
|
||||||
|
cfg->uid = pwd->pw_uid;
|
||||||
|
cfg->gid = pwd->pw_gid;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -192,6 +192,8 @@ struct config_file {
|
||||||
char* chrootdir;
|
char* chrootdir;
|
||||||
/** username to change to, if not "". */
|
/** username to change to, if not "". */
|
||||||
char* username;
|
char* username;
|
||||||
|
uid_t uid;
|
||||||
|
gid_t gid;
|
||||||
/** working directory */
|
/** working directory */
|
||||||
char* directory;
|
char* directory;
|
||||||
/** filename to log to. */
|
/** filename to log to. */
|
||||||
|
|
@ -282,6 +284,8 @@ struct config_file {
|
||||||
struct config_strlist* control_ifs;
|
struct config_strlist* control_ifs;
|
||||||
/** port number for the control port */
|
/** port number for the control port */
|
||||||
int control_port;
|
int control_port;
|
||||||
|
/** use certificates for remote control */
|
||||||
|
int remote_control_use_cert;
|
||||||
/** private key file for server */
|
/** private key file for server */
|
||||||
char* server_key_file;
|
char* server_key_file;
|
||||||
/** certificate file for server */
|
/** certificate file for server */
|
||||||
|
|
|
||||||
1926
util/configlexer.c
1926
util/configlexer.c
File diff suppressed because it is too large
Load diff
|
|
@ -315,6 +315,7 @@ remote-control{COLON} { YDVAR(0, VAR_REMOTE_CONTROL) }
|
||||||
control-enable{COLON} { YDVAR(1, VAR_CONTROL_ENABLE) }
|
control-enable{COLON} { YDVAR(1, VAR_CONTROL_ENABLE) }
|
||||||
control-interface{COLON} { YDVAR(1, VAR_CONTROL_INTERFACE) }
|
control-interface{COLON} { YDVAR(1, VAR_CONTROL_INTERFACE) }
|
||||||
control-port{COLON} { YDVAR(1, VAR_CONTROL_PORT) }
|
control-port{COLON} { YDVAR(1, VAR_CONTROL_PORT) }
|
||||||
|
control-use-cert{COLON} { YDVAR(1, VAR_CONTROL_USE_CERT) }
|
||||||
server-key-file{COLON} { YDVAR(1, VAR_SERVER_KEY_FILE) }
|
server-key-file{COLON} { YDVAR(1, VAR_SERVER_KEY_FILE) }
|
||||||
server-cert-file{COLON} { YDVAR(1, VAR_SERVER_CERT_FILE) }
|
server-cert-file{COLON} { YDVAR(1, VAR_SERVER_CERT_FILE) }
|
||||||
control-key-file{COLON} { YDVAR(1, VAR_CONTROL_KEY_FILE) }
|
control-key-file{COLON} { YDVAR(1, VAR_CONTROL_KEY_FILE) }
|
||||||
|
|
|
||||||
1191
util/configparser.c
1191
util/configparser.c
File diff suppressed because it is too large
Load diff
|
|
@ -139,59 +139,60 @@ extern int yydebug;
|
||||||
VAR_SERVER_CERT_FILE = 348,
|
VAR_SERVER_CERT_FILE = 348,
|
||||||
VAR_CONTROL_KEY_FILE = 349,
|
VAR_CONTROL_KEY_FILE = 349,
|
||||||
VAR_CONTROL_CERT_FILE = 350,
|
VAR_CONTROL_CERT_FILE = 350,
|
||||||
VAR_EXTENDED_STATISTICS = 351,
|
VAR_CONTROL_USE_CERT = 351,
|
||||||
VAR_LOCAL_DATA_PTR = 352,
|
VAR_EXTENDED_STATISTICS = 352,
|
||||||
VAR_JOSTLE_TIMEOUT = 353,
|
VAR_LOCAL_DATA_PTR = 353,
|
||||||
VAR_STUB_PRIME = 354,
|
VAR_JOSTLE_TIMEOUT = 354,
|
||||||
VAR_UNWANTED_REPLY_THRESHOLD = 355,
|
VAR_STUB_PRIME = 355,
|
||||||
VAR_LOG_TIME_ASCII = 356,
|
VAR_UNWANTED_REPLY_THRESHOLD = 356,
|
||||||
VAR_DOMAIN_INSECURE = 357,
|
VAR_LOG_TIME_ASCII = 357,
|
||||||
VAR_PYTHON = 358,
|
VAR_DOMAIN_INSECURE = 358,
|
||||||
VAR_PYTHON_SCRIPT = 359,
|
VAR_PYTHON = 359,
|
||||||
VAR_VAL_SIG_SKEW_MIN = 360,
|
VAR_PYTHON_SCRIPT = 360,
|
||||||
VAR_VAL_SIG_SKEW_MAX = 361,
|
VAR_VAL_SIG_SKEW_MIN = 361,
|
||||||
VAR_CACHE_MIN_TTL = 362,
|
VAR_VAL_SIG_SKEW_MAX = 362,
|
||||||
VAR_VAL_LOG_LEVEL = 363,
|
VAR_CACHE_MIN_TTL = 363,
|
||||||
VAR_AUTO_TRUST_ANCHOR_FILE = 364,
|
VAR_VAL_LOG_LEVEL = 364,
|
||||||
VAR_KEEP_MISSING = 365,
|
VAR_AUTO_TRUST_ANCHOR_FILE = 365,
|
||||||
VAR_ADD_HOLDDOWN = 366,
|
VAR_KEEP_MISSING = 366,
|
||||||
VAR_DEL_HOLDDOWN = 367,
|
VAR_ADD_HOLDDOWN = 367,
|
||||||
VAR_SO_RCVBUF = 368,
|
VAR_DEL_HOLDDOWN = 368,
|
||||||
VAR_EDNS_BUFFER_SIZE = 369,
|
VAR_SO_RCVBUF = 369,
|
||||||
VAR_PREFETCH = 370,
|
VAR_EDNS_BUFFER_SIZE = 370,
|
||||||
VAR_PREFETCH_KEY = 371,
|
VAR_PREFETCH = 371,
|
||||||
VAR_SO_SNDBUF = 372,
|
VAR_PREFETCH_KEY = 372,
|
||||||
VAR_SO_REUSEPORT = 373,
|
VAR_SO_SNDBUF = 373,
|
||||||
VAR_HARDEN_BELOW_NXDOMAIN = 374,
|
VAR_SO_REUSEPORT = 374,
|
||||||
VAR_IGNORE_CD_FLAG = 375,
|
VAR_HARDEN_BELOW_NXDOMAIN = 375,
|
||||||
VAR_LOG_QUERIES = 376,
|
VAR_IGNORE_CD_FLAG = 376,
|
||||||
VAR_TCP_UPSTREAM = 377,
|
VAR_LOG_QUERIES = 377,
|
||||||
VAR_SSL_UPSTREAM = 378,
|
VAR_TCP_UPSTREAM = 378,
|
||||||
VAR_SSL_SERVICE_KEY = 379,
|
VAR_SSL_UPSTREAM = 379,
|
||||||
VAR_SSL_SERVICE_PEM = 380,
|
VAR_SSL_SERVICE_KEY = 380,
|
||||||
VAR_SSL_PORT = 381,
|
VAR_SSL_SERVICE_PEM = 381,
|
||||||
VAR_FORWARD_FIRST = 382,
|
VAR_SSL_PORT = 382,
|
||||||
VAR_STUB_FIRST = 383,
|
VAR_FORWARD_FIRST = 383,
|
||||||
VAR_MINIMAL_RESPONSES = 384,
|
VAR_STUB_FIRST = 384,
|
||||||
VAR_RRSET_ROUNDROBIN = 385,
|
VAR_MINIMAL_RESPONSES = 385,
|
||||||
VAR_MAX_UDP_SIZE = 386,
|
VAR_RRSET_ROUNDROBIN = 386,
|
||||||
VAR_DELAY_CLOSE = 387,
|
VAR_MAX_UDP_SIZE = 387,
|
||||||
VAR_UNBLOCK_LAN_ZONES = 388,
|
VAR_DELAY_CLOSE = 388,
|
||||||
VAR_DNS64_PREFIX = 389,
|
VAR_UNBLOCK_LAN_ZONES = 389,
|
||||||
VAR_DNS64_SYNTHALL = 390,
|
VAR_DNS64_PREFIX = 390,
|
||||||
VAR_DNSTAP = 391,
|
VAR_DNS64_SYNTHALL = 391,
|
||||||
VAR_DNSTAP_ENABLE = 392,
|
VAR_DNSTAP = 392,
|
||||||
VAR_DNSTAP_SOCKET_PATH = 393,
|
VAR_DNSTAP_ENABLE = 393,
|
||||||
VAR_DNSTAP_SEND_IDENTITY = 394,
|
VAR_DNSTAP_SOCKET_PATH = 394,
|
||||||
VAR_DNSTAP_SEND_VERSION = 395,
|
VAR_DNSTAP_SEND_IDENTITY = 395,
|
||||||
VAR_DNSTAP_IDENTITY = 396,
|
VAR_DNSTAP_SEND_VERSION = 396,
|
||||||
VAR_DNSTAP_VERSION = 397,
|
VAR_DNSTAP_IDENTITY = 397,
|
||||||
VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES = 398,
|
VAR_DNSTAP_VERSION = 398,
|
||||||
VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES = 399,
|
VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES = 399,
|
||||||
VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES = 400,
|
VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES = 400,
|
||||||
VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES = 401,
|
VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES = 401,
|
||||||
VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES = 402,
|
VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES = 402,
|
||||||
VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES = 403
|
VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES = 403,
|
||||||
|
VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES = 404
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
/* Tokens. */
|
/* Tokens. */
|
||||||
|
|
@ -288,59 +289,60 @@ extern int yydebug;
|
||||||
#define VAR_SERVER_CERT_FILE 348
|
#define VAR_SERVER_CERT_FILE 348
|
||||||
#define VAR_CONTROL_KEY_FILE 349
|
#define VAR_CONTROL_KEY_FILE 349
|
||||||
#define VAR_CONTROL_CERT_FILE 350
|
#define VAR_CONTROL_CERT_FILE 350
|
||||||
#define VAR_EXTENDED_STATISTICS 351
|
#define VAR_CONTROL_USE_CERT 351
|
||||||
#define VAR_LOCAL_DATA_PTR 352
|
#define VAR_EXTENDED_STATISTICS 352
|
||||||
#define VAR_JOSTLE_TIMEOUT 353
|
#define VAR_LOCAL_DATA_PTR 353
|
||||||
#define VAR_STUB_PRIME 354
|
#define VAR_JOSTLE_TIMEOUT 354
|
||||||
#define VAR_UNWANTED_REPLY_THRESHOLD 355
|
#define VAR_STUB_PRIME 355
|
||||||
#define VAR_LOG_TIME_ASCII 356
|
#define VAR_UNWANTED_REPLY_THRESHOLD 356
|
||||||
#define VAR_DOMAIN_INSECURE 357
|
#define VAR_LOG_TIME_ASCII 357
|
||||||
#define VAR_PYTHON 358
|
#define VAR_DOMAIN_INSECURE 358
|
||||||
#define VAR_PYTHON_SCRIPT 359
|
#define VAR_PYTHON 359
|
||||||
#define VAR_VAL_SIG_SKEW_MIN 360
|
#define VAR_PYTHON_SCRIPT 360
|
||||||
#define VAR_VAL_SIG_SKEW_MAX 361
|
#define VAR_VAL_SIG_SKEW_MIN 361
|
||||||
#define VAR_CACHE_MIN_TTL 362
|
#define VAR_VAL_SIG_SKEW_MAX 362
|
||||||
#define VAR_VAL_LOG_LEVEL 363
|
#define VAR_CACHE_MIN_TTL 363
|
||||||
#define VAR_AUTO_TRUST_ANCHOR_FILE 364
|
#define VAR_VAL_LOG_LEVEL 364
|
||||||
#define VAR_KEEP_MISSING 365
|
#define VAR_AUTO_TRUST_ANCHOR_FILE 365
|
||||||
#define VAR_ADD_HOLDDOWN 366
|
#define VAR_KEEP_MISSING 366
|
||||||
#define VAR_DEL_HOLDDOWN 367
|
#define VAR_ADD_HOLDDOWN 367
|
||||||
#define VAR_SO_RCVBUF 368
|
#define VAR_DEL_HOLDDOWN 368
|
||||||
#define VAR_EDNS_BUFFER_SIZE 369
|
#define VAR_SO_RCVBUF 369
|
||||||
#define VAR_PREFETCH 370
|
#define VAR_EDNS_BUFFER_SIZE 370
|
||||||
#define VAR_PREFETCH_KEY 371
|
#define VAR_PREFETCH 371
|
||||||
#define VAR_SO_SNDBUF 372
|
#define VAR_PREFETCH_KEY 372
|
||||||
#define VAR_SO_REUSEPORT 373
|
#define VAR_SO_SNDBUF 373
|
||||||
#define VAR_HARDEN_BELOW_NXDOMAIN 374
|
#define VAR_SO_REUSEPORT 374
|
||||||
#define VAR_IGNORE_CD_FLAG 375
|
#define VAR_HARDEN_BELOW_NXDOMAIN 375
|
||||||
#define VAR_LOG_QUERIES 376
|
#define VAR_IGNORE_CD_FLAG 376
|
||||||
#define VAR_TCP_UPSTREAM 377
|
#define VAR_LOG_QUERIES 377
|
||||||
#define VAR_SSL_UPSTREAM 378
|
#define VAR_TCP_UPSTREAM 378
|
||||||
#define VAR_SSL_SERVICE_KEY 379
|
#define VAR_SSL_UPSTREAM 379
|
||||||
#define VAR_SSL_SERVICE_PEM 380
|
#define VAR_SSL_SERVICE_KEY 380
|
||||||
#define VAR_SSL_PORT 381
|
#define VAR_SSL_SERVICE_PEM 381
|
||||||
#define VAR_FORWARD_FIRST 382
|
#define VAR_SSL_PORT 382
|
||||||
#define VAR_STUB_FIRST 383
|
#define VAR_FORWARD_FIRST 383
|
||||||
#define VAR_MINIMAL_RESPONSES 384
|
#define VAR_STUB_FIRST 384
|
||||||
#define VAR_RRSET_ROUNDROBIN 385
|
#define VAR_MINIMAL_RESPONSES 385
|
||||||
#define VAR_MAX_UDP_SIZE 386
|
#define VAR_RRSET_ROUNDROBIN 386
|
||||||
#define VAR_DELAY_CLOSE 387
|
#define VAR_MAX_UDP_SIZE 387
|
||||||
#define VAR_UNBLOCK_LAN_ZONES 388
|
#define VAR_DELAY_CLOSE 388
|
||||||
#define VAR_DNS64_PREFIX 389
|
#define VAR_UNBLOCK_LAN_ZONES 389
|
||||||
#define VAR_DNS64_SYNTHALL 390
|
#define VAR_DNS64_PREFIX 390
|
||||||
#define VAR_DNSTAP 391
|
#define VAR_DNS64_SYNTHALL 391
|
||||||
#define VAR_DNSTAP_ENABLE 392
|
#define VAR_DNSTAP 392
|
||||||
#define VAR_DNSTAP_SOCKET_PATH 393
|
#define VAR_DNSTAP_ENABLE 393
|
||||||
#define VAR_DNSTAP_SEND_IDENTITY 394
|
#define VAR_DNSTAP_SOCKET_PATH 394
|
||||||
#define VAR_DNSTAP_SEND_VERSION 395
|
#define VAR_DNSTAP_SEND_IDENTITY 395
|
||||||
#define VAR_DNSTAP_IDENTITY 396
|
#define VAR_DNSTAP_SEND_VERSION 396
|
||||||
#define VAR_DNSTAP_VERSION 397
|
#define VAR_DNSTAP_IDENTITY 397
|
||||||
#define VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES 398
|
#define VAR_DNSTAP_VERSION 398
|
||||||
#define VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES 399
|
#define VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES 399
|
||||||
#define VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES 400
|
#define VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES 400
|
||||||
#define VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES 401
|
#define VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES 401
|
||||||
#define VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES 402
|
#define VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES 402
|
||||||
#define VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES 403
|
#define VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES 403
|
||||||
|
#define VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES 404
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -354,7 +356,7 @@ typedef union YYSTYPE
|
||||||
|
|
||||||
|
|
||||||
/* Line 2058 of yacc.c */
|
/* Line 2058 of yacc.c */
|
||||||
#line 358 "util/configparser.h"
|
#line 360 "util/configparser.h"
|
||||||
} YYSTYPE;
|
} YYSTYPE;
|
||||||
# define YYSTYPE_IS_TRIVIAL 1
|
# define YYSTYPE_IS_TRIVIAL 1
|
||||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||||
|
|
|
||||||
|
|
@ -95,6 +95,7 @@ extern struct config_parser_state* cfg_parser;
|
||||||
%token VAR_PRIVATE_DOMAIN VAR_REMOTE_CONTROL VAR_CONTROL_ENABLE
|
%token VAR_PRIVATE_DOMAIN VAR_REMOTE_CONTROL VAR_CONTROL_ENABLE
|
||||||
%token VAR_CONTROL_INTERFACE VAR_CONTROL_PORT VAR_SERVER_KEY_FILE
|
%token VAR_CONTROL_INTERFACE VAR_CONTROL_PORT VAR_SERVER_KEY_FILE
|
||||||
%token VAR_SERVER_CERT_FILE VAR_CONTROL_KEY_FILE VAR_CONTROL_CERT_FILE
|
%token VAR_SERVER_CERT_FILE VAR_CONTROL_KEY_FILE VAR_CONTROL_CERT_FILE
|
||||||
|
%token VAR_CONTROL_USE_CERT
|
||||||
%token VAR_EXTENDED_STATISTICS VAR_LOCAL_DATA_PTR VAR_JOSTLE_TIMEOUT
|
%token VAR_EXTENDED_STATISTICS VAR_LOCAL_DATA_PTR VAR_JOSTLE_TIMEOUT
|
||||||
%token VAR_STUB_PRIME VAR_UNWANTED_REPLY_THRESHOLD VAR_LOG_TIME_ASCII
|
%token VAR_STUB_PRIME VAR_UNWANTED_REPLY_THRESHOLD VAR_LOG_TIME_ASCII
|
||||||
%token VAR_DOMAIN_INSECURE VAR_PYTHON VAR_PYTHON_SCRIPT VAR_VAL_SIG_SKEW_MIN
|
%token VAR_DOMAIN_INSECURE VAR_PYTHON VAR_PYTHON_SCRIPT VAR_VAL_SIG_SKEW_MIN
|
||||||
|
|
@ -1271,7 +1272,7 @@ contents_rc: contents_rc content_rc
|
||||||
| ;
|
| ;
|
||||||
content_rc: rc_control_enable | rc_control_interface | rc_control_port |
|
content_rc: rc_control_enable | rc_control_interface | rc_control_port |
|
||||||
rc_server_key_file | rc_server_cert_file | rc_control_key_file |
|
rc_server_key_file | rc_server_cert_file | rc_control_key_file |
|
||||||
rc_control_cert_file
|
rc_control_cert_file | rc_control_use_cert
|
||||||
;
|
;
|
||||||
rc_control_enable: VAR_CONTROL_ENABLE STRING_ARG
|
rc_control_enable: VAR_CONTROL_ENABLE STRING_ARG
|
||||||
{
|
{
|
||||||
|
|
@ -1299,6 +1300,16 @@ rc_control_interface: VAR_CONTROL_INTERFACE STRING_ARG
|
||||||
yyerror("out of memory");
|
yyerror("out of memory");
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
rc_control_use_cert: VAR_CONTROL_USE_CERT STRING_ARG
|
||||||
|
{
|
||||||
|
OUTYY(("P(control_use_cert:%s)\n", $2));
|
||||||
|
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||||
|
yyerror("expected yes or no.");
|
||||||
|
else cfg_parser->cfg->remote_control_use_cert =
|
||||||
|
(strcmp($2, "yes")==0);
|
||||||
|
free($2);
|
||||||
|
}
|
||||||
|
;
|
||||||
rc_server_key_file: VAR_SERVER_KEY_FILE STRING_ARG
|
rc_server_key_file: VAR_SERVER_KEY_FILE STRING_ARG
|
||||||
{
|
{
|
||||||
OUTYY(("P(rc_server_key_file:%s)\n", $2));
|
OUTYY(("P(rc_server_key_file:%s)\n", $2));
|
||||||
|
|
|
||||||
|
|
@ -156,7 +156,7 @@ log_addr(enum verbosity_value v, const char* str,
|
||||||
case AF_INET6: family="ip6";
|
case AF_INET6: family="ip6";
|
||||||
sinaddr = &((struct sockaddr_in6*)addr)->sin6_addr;
|
sinaddr = &((struct sockaddr_in6*)addr)->sin6_addr;
|
||||||
break;
|
break;
|
||||||
case AF_UNIX: family="unix"; break;
|
case AF_LOCAL: family="local"; break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
if(inet_ntop(af, sinaddr, dest, (socklen_t)sizeof(dest)) == 0) {
|
if(inet_ntop(af, sinaddr, dest, (socklen_t)sizeof(dest)) == 0) {
|
||||||
|
|
@ -313,7 +313,7 @@ void log_name_addr(enum verbosity_value v, const char* str, uint8_t* zone,
|
||||||
case AF_INET6: family="";
|
case AF_INET6: family="";
|
||||||
sinaddr = &((struct sockaddr_in6*)addr)->sin6_addr;
|
sinaddr = &((struct sockaddr_in6*)addr)->sin6_addr;
|
||||||
break;
|
break;
|
||||||
case AF_UNIX: family="unix_family "; break;
|
case AF_LOCAL: family="local "; break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
if(inet_ntop(af, sinaddr, dest, (socklen_t)sizeof(dest)) == 0) {
|
if(inet_ntop(af, sinaddr, dest, (socklen_t)sizeof(dest)) == 0) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue