--- gvpe/src/vpn.C 2011/09/16 17:59:46 1.59 +++ gvpe/src/vpn.C 2015/07/15 23:04:06 1.68 @@ -1,6 +1,6 @@ /* vpn.C -- handle the protocol, encryption, handshaking etc. - Copyright (C) 2003-2008,2010,2011 Marc Lehmann + Copyright (C) 2003-2008,2010,2011,2013 Marc Lehmann This file is part of GVPE. @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -54,6 +55,8 @@ #include "util.h" #include "vpn.h" +using namespace std; + vpn network; // THE vpn (bad design...) ///////////////////////////////////////////////////////////////////////////// @@ -77,7 +80,7 @@ // the tricky part is rounding to the cipher key blocksize int mtu = conf.mtu - ETH_OVERHEAD - VPE_OVERHEAD - MAX_OVERHEAD; mtu += ETH_OVERHEAD - 6 - 6; // now we have the data portion - mtu -= mtu % EVP_CIPHER_block_size (CIPHER); // round + mtu -= mtu % BLOCK_SIZE (CIPHER); // round mtu -= ETH_OVERHEAD - 6 - 6; // and get interface mtu again char *env; @@ -112,13 +115,7 @@ { script_init_env (); - char *filename; - asprintf (&filename, - "%s/%s", - confbase, - ::conf.script_if_up ? ::conf.script_if_up : "if-up"); - - return filename; + return conf.config_filename (::conf.script_if_up, "if-up"); } int @@ -394,6 +391,74 @@ } bool +vpn::drop_privileges () +{ + if (::conf.change_root) + { + if (!strcmp (::conf.change_root, "/")) + { + char dir [L_tmpnam]; + if (!tmpnam (dir)) + { + slog (L_CRIT, _("unable to create anonymous root path.")); + return false; + } + + if (mkdir (dir, 0700)) + { + slog (L_CRIT, _("unable to create anonymous root directory.")); + return false; + } + + if (chdir (dir)) + { + slog (L_CRIT, _("unable to change to anonymous root directory.")); + return false; + } + + if (rmdir (dir)) + slog (L_ERR, _("unable to remove anonymous root directory, continuing.")); + } + else + { + if (chdir (::conf.change_root)) + { + slog (L_CRIT, _("%s: unable to change to specified root directory."), ::conf.change_root); + return false; + } + } + + if (chroot (".")) + { + slog (L_CRIT, _("unable to set new root directory.")); + return false; + } + + if (chdir ("/")) + { + slog (L_CRIT, _("unable to set cwd to new root directory.")); + return false; + } + } + + if (::conf.change_gid) + if (setgid (::conf.change_gid)) + { + slog (L_CRIT, _("unable to change group id to %d."), ::conf.change_gid); + return false; + } + + if (::conf.change_uid) + if (setuid (::conf.change_uid)) + { + slog (L_CRIT, _("unable to change user id to %d."), ::conf.change_uid); + return false; + } + + return true; +} + +bool vpn::send_ipv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) { set_tos (ipv4_fd, ipv4_tos, tos); @@ -486,9 +551,6 @@ || pkt->typ () >= vpn_packet::PT_MAX) slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)."), (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ()); - else if (dst > conns.size ()) - slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)."), - (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ()); else { connection *c = conns[src - 1]; @@ -518,14 +580,14 @@ switch (si.prot) { case PROT_IPv4: - return send_ipv4_packet (pkt, si, tos); + return send_ipv4_packet (pkt, si, tos); case PROT_UDPv4: - return send_udpv4_packet (pkt, si, tos); + return send_udpv4_packet (pkt, si, tos); #if ENABLE_TCP case PROT_TCPv4: - return send_tcpv4_packet (pkt, si, tos); + return send_tcpv4_packet (pkt, si, tos); #endif #if ENABLE_ICMP case PROT_ICMPv4: @@ -533,7 +595,7 @@ #endif #if ENABLE_DNS case PROT_DNSv4: - return send_dnsv4_packet (pkt, si, tos); + return send_dnsv4_packet (pkt, si, tos); #endif default: slog (L_CRIT, _("%s: FATAL: trying to send packet with unsupported protocol."), (const char *)si); @@ -561,7 +623,7 @@ pkt->len = len; // raw sockets deliver the ipv4 header, but don't expect it on sends - pkt->skip_ipv4_hdr (); + pkt->skip_hdr (pkt->ipv4_hdr_len ()); recv_vpn_packet (pkt, si); } @@ -608,7 +670,7 @@ { // raw sockets deliver the ipv4, but don't expect it on sends // this is slow, but... - pkt->skip_ipv4_hdr (ICMP_OVERHEAD - IP_OVERHEAD); + pkt->skip_hdr (pkt->ipv4_hdr_len () + (ICMP_OVERHEAD - IP_OVERHEAD)); recv_vpn_packet (pkt, si); } @@ -829,10 +891,10 @@ { connection *o = *i; - if (!o->is_direct - && o->si.valid () + if (o->si.valid () && c->si != o->si - && c == find_router_for (o)) + && c == find_router_for (o) + && !can_direct (THISNODE, o->conf)) { slog (L_DEBUG, _("%s: can now route packets via %s, re-keying connection."), o->conf->nodename, c->conf->nodename);