Add support for applying SELinux context

This commit is contained in:
Erik Ekman 2009-06-24 17:28:13 +00:00
parent 35b7f36bcc
commit 9e268419e7
8 changed files with 80 additions and 6 deletions

View file

@ -10,6 +10,8 @@ CHANGES:
- Any device name is now supported on Windows, fixes #47.
- Multiple installed TAP32 interfaces are now supported, fixes #46.
- Return nonzero if tunnel fails to open, fixes #62.
- Support for setting a SELinux context, based on patch by
Sebastien Raveau. Sample context file in doc/iodine.te
2009-06-01: 0.5.2 "WifiFree"
- Fixed client segfault on OS X, #57

25
doc/iodine.te Normal file
View file

@ -0,0 +1,25 @@
# Sample post-initialization SELinux policy for Iodine
policy_module(iodine, 1.1)
require {
type init_t;
type initrc_t;
type unconfined_t;
type unlabeled_t;
class udp_socket { read write };
class rawip_socket { write read };
class association recvfrom;
class unix_dgram_socket { create connect };
}
type iodine_t;
domain_type(iodine_t)
domain_dyntrans_type(initrc_t)
allow initrc_t iodine_t:process dyntransition;
allow iodine_t unconfined_t:udp_socket { read write };
allow iodine_t unconfined_t:rawip_socket { write read };
allow iodine_t unlabeled_t:association recvfrom;
allow iodine_t self:unix_dgram_socket { create connect };
corenet_raw_receive_generic_node(iodine_t)
corenet_rw_tun_tap_dev(iodine_t)

View file

@ -19,6 +19,8 @@ iodine, iodined \- tunnel IPv4 over DNS
.I device
.B ] [-m
.I fragsize
.B ] [-z
.I context
.B ]
.B [
.I nameserver
@ -47,7 +49,9 @@ iodine, iodined \- tunnel IPv4 over DNS
.I dnsport
.B ] [-P
.I password
.B ]
.B ] [-z
.I context
.B ]
.I tunnel_ip
.B [
.I /netmask
@ -89,6 +93,9 @@ and otherwise tunX.
Use 'password' to authenticate. If not used,
.B stdin
will be used as input. Only the first 32 characters will be used.
.TP
.B -z context
Apply SELinux 'context' after initialization.
.SS Client Options:
.TP
.B -m fragsize

View file

@ -41,6 +41,10 @@
#include <netinet/in.h>
#endif
#ifdef HAVE_SETCON
# include <selinux/selinux.h>
#endif
#include "common.h"
/* The raw header used when not using DNS protocol */
@ -167,6 +171,17 @@ do_chroot(char *newroot)
#endif
}
void
do_setcon(char *context)
{
#ifdef HAVE_SETCON
if (-1 == setcon(context))
err(1, "%s", context);
#else
warnx("No SELinux support built in");
#endif
}
void
do_detach()
{

View file

@ -90,6 +90,7 @@ int open_dns(int, in_addr_t);
void close_dns(int);
void do_chroot(char *);
void do_setcon(char *);
void do_detach();
void read_password(char*, size_t);

View file

@ -1104,7 +1104,7 @@ usage() {
extern char *__progname;
fprintf(stderr, "Usage: %s [-v] [-h] [-f] [-u user] [-t chrootdir] [-d device] "
"[-P password] [-m maxfragsize] [nameserver] topdomain\n", __progname);
"[-P password] [-m maxfragsize] [-z context] [nameserver] topdomain\n", __progname);
exit(2);
}
@ -1114,7 +1114,7 @@ help() {
fprintf(stderr, "iodine IP over DNS tunneling client\n");
fprintf(stderr, "Usage: %s [-v] [-h] [-f] [-u user] [-t chrootdir] [-d device] "
"[-P password] [-m maxfragsize] [nameserver] topdomain\n", __progname);
"[-P password] [-m maxfragsize] [-z context] [nameserver] topdomain\n", __progname);
fprintf(stderr, " -v to print version info and exit\n");
fprintf(stderr, " -h to print this help and exit\n");
fprintf(stderr, " -f to keep running in foreground\n");
@ -1123,6 +1123,7 @@ help() {
fprintf(stderr, " -d device to set tunnel device name\n");
fprintf(stderr, " -P password used for authentication (max 32 chars will be used)\n");
fprintf(stderr, " -m maxfragsize, to limit size of downstream packets\n");
fprintf(stderr, " -z context, to apply specified SELinux context after initialization\n");
fprintf(stderr, "nameserver is the IP number of the relaying nameserver, if absent /etc/resolv.conf is used\n");
fprintf(stderr, "topdomain is the FQDN that is delegated to the tunnel endpoint.\n");
@ -1151,6 +1152,7 @@ main(int argc, char **argv)
char *username;
int foreground;
char *newroot;
char *context;
char *device;
int choice;
int tun_fd;
@ -1163,6 +1165,7 @@ main(int argc, char **argv)
username = NULL;
foreground = 0;
newroot = NULL;
context = NULL;
device = NULL;
chunkid = 0;
@ -1222,6 +1225,9 @@ main(int argc, char **argv)
autodetect_frag_size = 0;
max_downstream_frag_size = atoi(optarg);
break;
case 'z':
context = optarg;
break;
default:
usage();
/* NOTREACHED */
@ -1321,6 +1327,9 @@ main(int argc, char **argv)
}
#endif
}
if (context != NULL)
do_setcon(context);
downstream_seqno = 0;
downstream_fragment = 0;

View file

@ -981,7 +981,7 @@ usage() {
extern char *__progname;
fprintf(stderr, "Usage: %s [-v] [-h] [-c] [-s] [-f] [-D] [-u user] "
"[-t chrootdir] [-d device] [-m mtu] "
"[-t chrootdir] [-d device] [-m mtu] [-z context] "
"[-l ip address to listen on] [-p port] [-n external ip] [-b dnsport] [-P password]"
" tunnel_ip[/netmask] topdomain\n", __progname);
exit(2);
@ -993,7 +993,7 @@ help() {
fprintf(stderr, "iodine IP over DNS tunneling server\n");
fprintf(stderr, "Usage: %s [-v] [-h] [-c] [-s] [-f] [-D] [-u user] "
"[-t chrootdir] [-d device] [-m mtu] "
"[-t chrootdir] [-d device] [-m mtu] [-z context] "
"[-l ip address to listen on] [-p port] [-n external ip] [-b dnsport] [-P password]"
" tunnel_ip[/netmask] topdomain\n", __progname);
fprintf(stderr, " -v to print version info and exit\n");
@ -1007,6 +1007,7 @@ help() {
fprintf(stderr, " -t dir to chroot to directory dir\n");
fprintf(stderr, " -d device to set tunnel device name\n");
fprintf(stderr, " -m mtu to set tunnel device mtu\n");
fprintf(stderr, " -z context to apply SELinux context after initialization\n");
fprintf(stderr, " -l ip address to listen on for incoming dns traffic "
"(default 0.0.0.0)\n");
fprintf(stderr, " -p port to listen on for incoming dns traffic (default 53)\n");
@ -1039,6 +1040,7 @@ main(int argc, char **argv)
int foreground;
char *username;
char *newroot;
char *context;
char *device;
int dnsd_fd;
int tun_fd;
@ -1057,6 +1059,7 @@ main(int argc, char **argv)
username = NULL;
newroot = NULL;
context = NULL;
device = NULL;
foreground = 0;
bind_enable = 0;
@ -1090,7 +1093,7 @@ main(int argc, char **argv)
srand(time(NULL));
fw_query_init();
while ((choice = getopt(argc, argv, "vcsfhDu:t:d:m:l:p:n:b:P:")) != -1) {
while ((choice = getopt(argc, argv, "vcsfhDu:t:d:m:l:p:n:b:P:z:")) != -1) {
switch(choice) {
case 'v':
version();
@ -1142,6 +1145,9 @@ main(int argc, char **argv)
/* XXX: find better way of cleaning up ps(1) */
memset(optarg, 0, strlen(optarg));
break;
case 'z':
context = optarg;
break;
default:
usage();
break;
@ -1287,6 +1293,9 @@ main(int argc, char **argv)
#endif
}
if (context != NULL)
do_setcon(context);
#ifndef WINDOWS32
openlog(__progname, LOG_NOWAIT, LOG_DAEMON);
#endif

View file

@ -16,6 +16,9 @@ link)
windows32)
echo '-lws2_32 -liphlpapi';
;;
Linux)
[ -e /usr/include/selinux/selinux.h ] && echo '-lselinux';
;;
esac
;;
cflags)
@ -23,6 +26,9 @@ cflags)
BeOS)
echo '-Dsocklen_t=int';
;;
Linux)
[ -e /usr/include/selinux/selinux.h ] && echo '-DHAVE_SETCON';
;;
esac
;;
*)