mirror of
https://github.com/irssi/irssi.git
synced 2026-08-17 07:32:04 +02:00
/connect works - although only with IP addresses.
This commit is contained in:
parent
3200c381db
commit
cec68557aa
5 changed files with 165 additions and 6 deletions
|
|
@ -19,21 +19,147 @@
|
|||
*/
|
||||
|
||||
#include "module.h"
|
||||
#include "network.h"
|
||||
#include "signals.h"
|
||||
#include "commands.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/capsicum.h>
|
||||
#include <sys/nv.h>
|
||||
#include <sys/procdesc.h>
|
||||
#include <sys/socket.h>
|
||||
#include <string.h>
|
||||
|
||||
static int symbiontfds[2];
|
||||
|
||||
gboolean capsicum_enabled(void)
|
||||
{
|
||||
u_int mode;
|
||||
int error;
|
||||
|
||||
error = cap_getmode(&mode);
|
||||
if (error != 0)
|
||||
return FALSE;
|
||||
|
||||
if (mode == 0)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int capsicum_net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip)
|
||||
{
|
||||
nvlist_t *nvl;
|
||||
int error, saved_errno, sock;
|
||||
|
||||
/* Send request to the symbiont. */
|
||||
nvl = nvlist_create(0);
|
||||
nvlist_add_binary(nvl, "ip", ip, sizeof(*ip));
|
||||
nvlist_add_number(nvl, "port", port);
|
||||
if (my_ip != NULL) {
|
||||
/* nvlist_add_binary(3) can't handle NULL values. */
|
||||
nvlist_add_binary(nvl, "my_ip", my_ip, sizeof(*my_ip));
|
||||
}
|
||||
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;
|
||||
}
|
||||
if (nvlist_exists_descriptor(nvl, "sock")) {
|
||||
sock = nvlist_take_descriptor(nvl, "sock");
|
||||
} else {
|
||||
sock = -1;
|
||||
}
|
||||
saved_errno = nvlist_get_number(nvl, "errno");
|
||||
nvlist_destroy(nvl);
|
||||
errno = saved_errno;
|
||||
|
||||
return sock;
|
||||
}
|
||||
|
||||
static void cmd_capsicum(const char *data, SERVER_REC *server, void *item)
|
||||
{
|
||||
command_runsub("capsicum", data, server, item);
|
||||
}
|
||||
|
||||
static int start_symbiont(void)
|
||||
{
|
||||
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) {
|
||||
g_warning("socketpair: %s", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
pid = pdfork(&childfd, PD_CLOEXEC);
|
||||
if (pid < 0) {
|
||||
g_warning("pdfork: %s", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (pid > 0) {
|
||||
close(symbiontfds[0]);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
static void cmd_capsicum_enter(void)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = start_symbiont();
|
||||
if (error != 0) {
|
||||
signal_emit("capability mode failed", 1, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
error = cap_enter();
|
||||
if (error != 0) {
|
||||
signal_emit("capability mode failed", 1, strerror(errno));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue