mirror of
https://github.com/irssi/irssi.git
synced 2024-12-04 14:46:39 -05:00
Make DNS work in capability mode.
Signed-off-by: Edward Tomasz Napierala <trasz@FreeBSD.org>
This commit is contained in:
parent
f4546be7ec
commit
509eca76f0
@ -31,6 +31,9 @@
|
||||
#include <sys/socket.h>
|
||||
#include <string.h>
|
||||
|
||||
#define OPCODE_CONNECT 1
|
||||
#define OPCODE_GETHOSTBYNAME 2
|
||||
|
||||
static int symbiontfds[2];
|
||||
|
||||
gboolean capsicum_enabled(void)
|
||||
@ -55,6 +58,7 @@ int capsicum_net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip)
|
||||
|
||||
/* Send request to the symbiont. */
|
||||
nvl = nvlist_create(0);
|
||||
nvlist_add_number(nvl, "opcode", OPCODE_CONNECT);
|
||||
nvlist_add_binary(nvl, "ip", ip, sizeof(*ip));
|
||||
nvlist_add_number(nvl, "port", port);
|
||||
if (my_ip != NULL) {
|
||||
@ -86,12 +90,139 @@ int capsicum_net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip)
|
||||
return sock;
|
||||
}
|
||||
|
||||
int capsicum_net_gethostbyname(const char *addr, IPADDR *ip4, IPADDR *ip6)
|
||||
{
|
||||
nvlist_t *nvl;
|
||||
IPADDR *received_ip4, *received_ip6;
|
||||
int error, ret, saved_errno;
|
||||
|
||||
/* Send request to the symbiont. */
|
||||
nvl = nvlist_create(0);
|
||||
nvlist_add_number(nvl, "opcode", OPCODE_GETHOSTBYNAME);
|
||||
nvlist_add_string(nvl, "addr", addr);
|
||||
error = nvlist_send(symbiontfds[1], nvl);
|
||||
nvlist_destroy(nvl);
|
||||
if (error != 0) {
|
||||
g_warning("nvlist_send: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Receive response. */
|
||||
nvl = nvlist_recv(symbiontfds[1], 0);
|
||||
if (nvl == NULL) {
|
||||
g_warning("nvlist_recv: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
received_ip4 = nvlist_get_binary(nvl, "ip4", NULL);
|
||||
received_ip6 = nvlist_get_binary(nvl, "ip6", NULL);
|
||||
memcpy(ip4, received_ip4, sizeof(*ip4));
|
||||
memcpy(ip6, received_ip6, sizeof(*ip6));
|
||||
|
||||
ret = nvlist_get_number(nvl, "ret");
|
||||
saved_errno = nvlist_get_number(nvl, "errno");
|
||||
nvlist_destroy(nvl);
|
||||
errno = saved_errno;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
nvlist_t *symbiont_connect(const nvlist_t *request)
|
||||
{
|
||||
nvlist_t *response;
|
||||
IPADDR *ip, *my_ip;
|
||||
int port, saved_errno, sock;
|
||||
|
||||
ip = nvlist_get_binary(request, "ip", NULL);
|
||||
port = (int)nvlist_get_number(request, "port");
|
||||
if (nvlist_exists(request, "my_ip"))
|
||||
my_ip = nvlist_get_binary(request, "my_ip", NULL);
|
||||
else
|
||||
my_ip = NULL;
|
||||
|
||||
/* Connect. */
|
||||
sock = net_connect_ip_handle(ip, port, my_ip);
|
||||
saved_errno = errno;
|
||||
|
||||
/* Send back the socket fd. */
|
||||
response = nvlist_create(0);
|
||||
|
||||
if (sock != -1)
|
||||
nvlist_move_descriptor(response, "sock", sock);
|
||||
nvlist_add_number(response, "errno", saved_errno);
|
||||
|
||||
return (response);
|
||||
}
|
||||
|
||||
nvlist_t *symbiont_gethostbyname(const nvlist_t *request)
|
||||
{
|
||||
nvlist_t *response;
|
||||
IPADDR ip4, ip6;
|
||||
const char *addr;
|
||||
int ret, saved_errno;
|
||||
|
||||
addr = nvlist_get_string(request, "addr");
|
||||
|
||||
/* Connect. */
|
||||
ret = net_gethostbyname(addr, &ip4, &ip6);
|
||||
saved_errno = errno;
|
||||
|
||||
/* Send back the IPs. */
|
||||
response = nvlist_create(0);
|
||||
|
||||
nvlist_add_number(response, "ret", ret);
|
||||
nvlist_add_number(response, "errno", saved_errno);
|
||||
nvlist_add_binary(response, "ip4", &ip4, sizeof(ip4));
|
||||
nvlist_add_binary(response, "ip6", &ip6, sizeof(ip6));
|
||||
|
||||
return (response);
|
||||
}
|
||||
|
||||
/*
|
||||
* Child process, running outside the Capsicum sandbox.
|
||||
*/
|
||||
_Noreturn static void symbiont(void)
|
||||
{
|
||||
nvlist_t *request, *response;
|
||||
int error, opcode;
|
||||
|
||||
setproctitle("capsicum symbiont");
|
||||
close(symbiontfds[1]);
|
||||
close(0);
|
||||
close(1);
|
||||
close(2);
|
||||
|
||||
for (;;) {
|
||||
/* Receive parameters from the main irssi process. */
|
||||
request = nvlist_recv(symbiontfds[0], 0);
|
||||
if (request == NULL)
|
||||
exit(1);
|
||||
|
||||
opcode = nvlist_get_number(request, "opcode");
|
||||
switch (opcode) {
|
||||
case OPCODE_CONNECT:
|
||||
response = symbiont_connect(request);
|
||||
break;
|
||||
case OPCODE_GETHOSTBYNAME:
|
||||
response = symbiont_gethostbyname(request);
|
||||
break;
|
||||
default:
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Send back the response. */
|
||||
error = nvlist_send(symbiontfds[0], response);
|
||||
if (error != 0)
|
||||
exit(1);
|
||||
nvlist_destroy(request);
|
||||
nvlist_destroy(response);
|
||||
}
|
||||
}
|
||||
|
||||
static int start_symbiont(void)
|
||||
{
|
||||
int childfd, error;
|
||||
pid_t pid;
|
||||
nvlist_t *nvl;
|
||||
IPADDR *ip, *my_ip;
|
||||
int childfd, error, port, saved_errno, sock;
|
||||
|
||||
error = socketpair(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, symbiontfds);
|
||||
if (error != 0) {
|
||||
@ -110,40 +241,8 @@ static int start_symbiont(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* We're the child, running outside the Capsicum sandbox. */
|
||||
setproctitle("capsicum symbiont");
|
||||
close(symbiontfds[1]);
|
||||
close(0);
|
||||
close(1);
|
||||
close(2);
|
||||
for (;;) {
|
||||
/* Receive parameters from the main irssi process. */
|
||||
nvl = nvlist_recv(symbiontfds[0], 0);
|
||||
if (nvl == NULL)
|
||||
exit(1);
|
||||
ip = nvlist_get_binary(nvl, "ip", NULL);
|
||||
port = (int)nvlist_get_number(nvl, "port");
|
||||
if (nvlist_exists(nvl, "my_ip"))
|
||||
my_ip = nvlist_get_binary(nvl, "my_ip", NULL);
|
||||
else
|
||||
my_ip = NULL;
|
||||
|
||||
/* Connect. */
|
||||
sock = net_connect_ip_handle(ip, port, my_ip);
|
||||
saved_errno = errno;
|
||||
|
||||
/* Send back the socket fd. */
|
||||
nvlist_destroy(nvl);
|
||||
nvl = nvlist_create(0);
|
||||
|
||||
if (sock != -1)
|
||||
nvlist_move_descriptor(nvl, "sock", sock);
|
||||
nvlist_add_number(nvl, "errno", saved_errno);
|
||||
error = nvlist_send(symbiontfds[0], nvl);
|
||||
if (error != 0)
|
||||
exit(1);
|
||||
nvlist_destroy(nvl);
|
||||
}
|
||||
symbiont();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
static void cmd_capsicum(const char *data, SERVER_REC *server, void *item)
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
gboolean capsicum_enabled(void);
|
||||
int capsicum_net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip);
|
||||
int capsicum_net_gethostbyname(const char *addr, IPADDR *ip4, IPADDR *ip6);
|
||||
|
||||
void capsicum_init(void);
|
||||
void capsicum_deinit(void);
|
||||
|
@ -406,6 +406,11 @@ int net_gethostbyname(const char *addr, IPADDR *ip4, IPADDR *ip6)
|
||||
struct addrinfo hints, *ai, *ailist;
|
||||
int ret, count_v4, count_v6, use_v4, use_v6;
|
||||
|
||||
#ifdef HAVE_CAPSICUM
|
||||
if (capsicum_enabled())
|
||||
return (capsicum_net_gethostbyname(addr, ip4, ip6));
|
||||
#endif
|
||||
|
||||
g_return_val_if_fail(addr != NULL, -1);
|
||||
|
||||
memset(ip4, 0, sizeof(IPADDR));
|
||||
|
Loading…
Reference in New Issue
Block a user