ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/vpn.C
(Generate patch)

Comparing gvpe/src/vpn.C (file contents):
Revision 1.54 by pcg, Mon Mar 23 15:22:00 2009 UTC vs.
Revision 1.65 by root, Tue Jul 16 16:44:37 2013 UTC

1/* 1/*
2 vpn.C -- handle the protocol, encryption, handshaking etc. 2 vpn.C -- handle the protocol, encryption, handshaking etc.
3 Copyright (C) 2003-2008 Marc Lehmann <gvpe@schmorp.de> 3 Copyright (C) 2003-2008,2010,2011,2013 Marc Lehmann <gvpe@schmorp.de>
4 4
5 This file is part of GVPE. 5 This file is part of GVPE.
6 6
7 GVPE is free software; you can redistribute it and/or modify it 7 GVPE is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the 8 under the terms of the GNU General Public License as published by the
38#include <cstdlib> 38#include <cstdlib>
39 39
40#include <sys/types.h> 40#include <sys/types.h>
41#include <sys/socket.h> 41#include <sys/socket.h>
42#include <sys/wait.h> 42#include <sys/wait.h>
43#include <sys/stat.h>
43#include <errno.h> 44#include <errno.h>
44#include <time.h> 45#include <time.h>
45#include <unistd.h> 46#include <unistd.h>
46#include <fcntl.h> 47#include <fcntl.h>
47#include <sys/socket.h> 48#include <sys/socket.h>
52 53
53#include "connection.h" 54#include "connection.h"
54#include "util.h" 55#include "util.h"
55#include "vpn.h" 56#include "vpn.h"
56 57
58using namespace std;
59
57vpn network; // THE vpn (bad design...) 60vpn network; // THE vpn (bad design...)
58 61
59///////////////////////////////////////////////////////////////////////////// 62/////////////////////////////////////////////////////////////////////////////
60 63
61static void inline 64static void inline
75{ 78{
76 // the tunnel device mtu should be the physical mtu - overhead 79 // the tunnel device mtu should be the physical mtu - overhead
77 // the tricky part is rounding to the cipher key blocksize 80 // the tricky part is rounding to the cipher key blocksize
78 int mtu = conf.mtu - ETH_OVERHEAD - VPE_OVERHEAD - MAX_OVERHEAD; 81 int mtu = conf.mtu - ETH_OVERHEAD - VPE_OVERHEAD - MAX_OVERHEAD;
79 mtu += ETH_OVERHEAD - 6 - 6; // now we have the data portion 82 mtu += ETH_OVERHEAD - 6 - 6; // now we have the data portion
80 mtu -= mtu % EVP_CIPHER_block_size (CIPHER); // round 83 mtu -= mtu % BLOCK_SIZE (CIPHER); // round
81 mtu -= ETH_OVERHEAD - 6 - 6; // and get interface mtu again 84 mtu -= ETH_OVERHEAD - 6 - 6; // and get interface mtu again
82 85
83 char *env; 86 char *env;
84 asprintf (&env, "CONFBASE=%s", confbase); putenv (env); 87 asprintf (&env, "CONFBASE=%s", confbase); putenv (env);
85 asprintf (&env, "IFNAME=%s", tap->interface ()); putenv (env); 88 asprintf (&env, "IFNAME=%s", tap->interface ()); putenv (env);
135 fcntl (fd, F_SETFL, O_NONBLOCK); 138 fcntl (fd, F_SETFL, O_NONBLOCK);
136 fcntl (fd, F_SETFD, FD_CLOEXEC); 139 fcntl (fd, F_SETFD, FD_CLOEXEC);
137 140
138#ifdef SO_MARK 141#ifdef SO_MARK
139 if (::conf.nfmark) 142 if (::conf.nfmark)
140 setsockopt (ipv4_fd, SOL_SOCKET, SO_MARK, &::conf.nfmark, sizeof ::conf.nfmark); 143 if (setsockopt (fd, SOL_SOCKET, SO_MARK, &::conf.nfmark, sizeof ::conf.nfmark))
144 slog (L_WARN, _("unable to set nfmark on %s socket: %s"), strprotocol (prot), strerror (errno));
141#endif 145#endif
142 146
143 return fd; 147 return fd;
144} 148}
145 149
388 } 392 }
389 393
390 tap_ev_watcher.start (tap->fd, EV_READ); 394 tap_ev_watcher.start (tap->fd, EV_READ);
391 395
392 return 0; 396 return 0;
397}
398
399bool
400vpn::drop_privileges ()
401{
402 if (::conf.change_root)
403 {
404 if (!strcmp (::conf.change_root, "/"))
405 {
406 char dir [L_tmpnam];
407 if (!tmpnam (dir))
408 {
409 slog (L_CRIT, _("unable to create anonymous root path."));
410 return false;
411 }
412
413 if (mkdir (dir, 0700))
414 {
415 slog (L_CRIT, _("unable to crate anonymous root directory."));
416 return false;
417 }
418
419 if (chdir (dir))
420 {
421 slog (L_CRIT, _("unable to change to anonymous root directory."));
422 return false;
423 }
424
425 if (rmdir (dir))
426 slog (L_ERR, _("unable to remove anonymous root directory, continuing."));
427 }
428 else
429 {
430 if (chdir (::conf.change_root))
431 {
432 slog (L_CRIT, _("%s: unable to change to specified root directory."), ::conf.change_root);
433 return false;
434 }
435 }
436
437 if (chroot ("."))
438 {
439 slog (L_CRIT, _("unable to set new root directory."));
440 return false;
441 }
442
443 if (chdir ("/"))
444 {
445 slog (L_CRIT, _("unable to set cwd to new root directory."));
446 return false;
447 }
448 }
449
450 if (::conf.change_gid)
451 if (setgid (::conf.change_gid))
452 {
453 slog (L_CRIT, _("unable to change group id to %d."), ::conf.change_gid);
454 return false;
455 }
456
457 if (::conf.change_uid)
458 if (setuid (::conf.change_uid))
459 {
460 slog (L_CRIT, _("unable to change user id to %d."), ::conf.change_uid);
461 return false;
462 }
463
464 return true;
393} 465}
394 466
395bool 467bool
396vpn::send_ipv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) 468vpn::send_ipv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
397{ 469{
481 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst (), pkt->len); 553 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst (), pkt->len);
482 554
483 if (src == 0 || src > conns.size () 555 if (src == 0 || src > conns.size ()
484 || dst > conns.size () 556 || dst > conns.size ()
485 || pkt->typ () >= vpn_packet::PT_MAX) 557 || pkt->typ () >= vpn_packet::PT_MAX)
486 slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)."),
487 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ());
488 else if (dst > conns.size ())
489 slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)."), 558 slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)."),
490 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ()); 559 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ());
491 else 560 else
492 { 561 {
493 connection *c = conns[src - 1]; 562 connection *c = conns[src - 1];
515vpn::send_vpn_packet (vpn_packet *pkt, const sockinfo &si, int tos) 584vpn::send_vpn_packet (vpn_packet *pkt, const sockinfo &si, int tos)
516{ 585{
517 switch (si.prot) 586 switch (si.prot)
518 { 587 {
519 case PROT_IPv4: 588 case PROT_IPv4:
520 return send_ipv4_packet (pkt, si, tos); 589 return send_ipv4_packet (pkt, si, tos);
521 590
522 case PROT_UDPv4: 591 case PROT_UDPv4:
523 return send_udpv4_packet (pkt, si, tos); 592 return send_udpv4_packet (pkt, si, tos);
524 593
525#if ENABLE_TCP 594#if ENABLE_TCP
526 case PROT_TCPv4: 595 case PROT_TCPv4:
527 return send_tcpv4_packet (pkt, si, tos); 596 return send_tcpv4_packet (pkt, si, tos);
528#endif 597#endif
529#if ENABLE_ICMP 598#if ENABLE_ICMP
530 case PROT_ICMPv4: 599 case PROT_ICMPv4:
531 return send_icmpv4_packet (pkt, si, tos); 600 return send_icmpv4_packet (pkt, si, tos);
532#endif 601#endif
533#if ENABLE_DNS 602#if ENABLE_DNS
534 case PROT_DNSv4: 603 case PROT_DNSv4:
535 return send_dnsv4_packet (pkt, si, tos); 604 return send_dnsv4_packet (pkt, si, tos);
536#endif 605#endif
537 default: 606 default:
538 slog (L_CRIT, _("%s: FATAL: trying to send packet with unsupported protocol."), (const char *)si); 607 slog (L_CRIT, _("%s: FATAL: trying to send packet with unsupported protocol."), (const char *)si);
539 } 608 }
540 609
558 if (len > 0) 627 if (len > 0)
559 { 628 {
560 pkt->len = len; 629 pkt->len = len;
561 630
562 // raw sockets deliver the ipv4 header, but don't expect it on sends 631 // raw sockets deliver the ipv4 header, but don't expect it on sends
563 pkt->skip_hdr (IP_OVERHEAD); 632 pkt->skip_hdr (pkt->ipv4_hdr_len ());
564 633
565 recv_vpn_packet (pkt, si); 634 recv_vpn_packet (pkt, si);
566 } 635 }
567 else 636 else
568 { 637 {
605 if (hdr->type == ::conf.icmp_type 674 if (hdr->type == ::conf.icmp_type
606 && hdr->code == 255) 675 && hdr->code == 255)
607 { 676 {
608 // raw sockets deliver the ipv4, but don't expect it on sends 677 // raw sockets deliver the ipv4, but don't expect it on sends
609 // this is slow, but... 678 // this is slow, but...
610 pkt->skip_hdr (ICMP_OVERHEAD); 679 pkt->skip_hdr (pkt->ipv4_hdr_len () + (ICMP_OVERHEAD - IP_OVERHEAD));
611 680
612 recv_vpn_packet (pkt, si); 681 recv_vpn_packet (pkt, si);
613 } 682 }
614 } 683 }
615 else 684 else
757 826
758 for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c) 827 for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c)
759 (*c)->establish_connection (); 828 (*c)->establish_connection ();
760} 829}
761 830
831bool
762bool vpn::can_direct (conf_node *src, conf_node *dst) const 832vpn::can_direct (conf_node *src, conf_node *dst) const
763{ 833{
764 return src != dst 834 return src != dst
765 && src->may_direct (dst) 835 && src->may_direct (dst)
766 && dst->may_direct (src) 836 && dst->may_direct (src)
767 && (((src->protocols & dst->protocols) && src->connectmode == conf_node::C_ALWAYS) 837 && (((src->protocols & dst->protocols) && src->connectmode == conf_node::C_ALWAYS)
768 || (src->protocols & dst->connectable_protocols ())); 838 || (src->protocols & dst->connectable_protocols ()));
769} 839}
770 840
771// only works for indirect and routed connections: find a router 841// only works for indirect and routed connections: find a router
772// from THISNODE to dst 842// from THISNODE to dst
843connection *
773connection *vpn::find_router_for (const connection *dst) 844vpn::find_router_for (const connection *dst)
774{ 845{
775 connection *router = 0; 846 connection *router = 0;
776 847
777 // first try to find a router with a direct connection, route there 848 // first try to find a router with a direct connection, route there
778 // regardless of any other considerations. 849 // regardless of any other considerations.
817 } 888 }
818 889
819 return router; 890 return router;
820} 891}
821 892
893void
822void vpn::connection_established (connection *c) 894vpn::connection_established (connection *c)
823{ 895{
824 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i) 896 for (conns_vector::iterator i = conns.begin (); i != conns.end (); ++i)
825 { 897 {
826 connection *o = *i; 898 connection *o = *i;
827 899
835 o->rekey (); 907 o->rekey ();
836 } 908 }
837 } 909 }
838} 910}
839 911
912void
840void vpn::send_connect_request (connection *c) 913vpn::send_connect_request (connection *c)
841{ 914{
842 connection *r = find_router_for (c); 915 connection *r = find_router_for (c);
843 916
844 if (r) 917 if (r)
845 { 918 {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines