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.59 by root, Fri Sep 16 17:59:46 2011 UTC vs.
Revision 1.66 by root, Thu Jul 18 13:35:16 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,2010,2011 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);
110inline const char * 113inline const char *
111vpn::script_if_up () 114vpn::script_if_up ()
112{ 115{
113 script_init_env (); 116 script_init_env ();
114 117
115 char *filename; 118 return conf.config_filename (::conf.script_if_up, "if-up");
116 asprintf (&filename,
117 "%s/%s",
118 confbase,
119 ::conf.script_if_up ? ::conf.script_if_up : "if-up");
120
121 return filename;
122} 119}
123 120
124int 121int
125vpn::setup_socket (u8 prot, int family, int type, int proto) 122vpn::setup_socket (u8 prot, int family, int type, int proto)
126{ 123{
389 } 386 }
390 387
391 tap_ev_watcher.start (tap->fd, EV_READ); 388 tap_ev_watcher.start (tap->fd, EV_READ);
392 389
393 return 0; 390 return 0;
391}
392
393bool
394vpn::drop_privileges ()
395{
396 if (::conf.change_root)
397 {
398 if (!strcmp (::conf.change_root, "/"))
399 {
400 char dir [L_tmpnam];
401 if (!tmpnam (dir))
402 {
403 slog (L_CRIT, _("unable to create anonymous root path."));
404 return false;
405 }
406
407 if (mkdir (dir, 0700))
408 {
409 slog (L_CRIT, _("unable to crate anonymous root directory."));
410 return false;
411 }
412
413 if (chdir (dir))
414 {
415 slog (L_CRIT, _("unable to change to anonymous root directory."));
416 return false;
417 }
418
419 if (rmdir (dir))
420 slog (L_ERR, _("unable to remove anonymous root directory, continuing."));
421 }
422 else
423 {
424 if (chdir (::conf.change_root))
425 {
426 slog (L_CRIT, _("%s: unable to change to specified root directory."), ::conf.change_root);
427 return false;
428 }
429 }
430
431 if (chroot ("."))
432 {
433 slog (L_CRIT, _("unable to set new root directory."));
434 return false;
435 }
436
437 if (chdir ("/"))
438 {
439 slog (L_CRIT, _("unable to set cwd to new root directory."));
440 return false;
441 }
442 }
443
444 if (::conf.change_gid)
445 if (setgid (::conf.change_gid))
446 {
447 slog (L_CRIT, _("unable to change group id to %d."), ::conf.change_gid);
448 return false;
449 }
450
451 if (::conf.change_uid)
452 if (setuid (::conf.change_uid))
453 {
454 slog (L_CRIT, _("unable to change user id to %d."), ::conf.change_uid);
455 return false;
456 }
457
458 return true;
394} 459}
395 460
396bool 461bool
397vpn::send_ipv4_packet (vpn_packet *pkt, const sockinfo &si, int tos) 462vpn::send_ipv4_packet (vpn_packet *pkt, const sockinfo &si, int tos)
398{ 463{
482 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst (), pkt->len); 547 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst (), pkt->len);
483 548
484 if (src == 0 || src > conns.size () 549 if (src == 0 || src > conns.size ()
485 || dst > conns.size () 550 || dst > conns.size ()
486 || pkt->typ () >= vpn_packet::PT_MAX) 551 || pkt->typ () >= vpn_packet::PT_MAX)
487 slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)."),
488 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ());
489 else if (dst > conns.size ())
490 slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)."), 552 slog (L_WARN, _("(%s): received corrupted packet type %d (src %d, dst %d)."),
491 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ()); 553 (const char *)rsi, pkt->typ (), pkt->src (), pkt->dst ());
492 else 554 else
493 { 555 {
494 connection *c = conns[src - 1]; 556 connection *c = conns[src - 1];
516vpn::send_vpn_packet (vpn_packet *pkt, const sockinfo &si, int tos) 578vpn::send_vpn_packet (vpn_packet *pkt, const sockinfo &si, int tos)
517{ 579{
518 switch (si.prot) 580 switch (si.prot)
519 { 581 {
520 case PROT_IPv4: 582 case PROT_IPv4:
521 return send_ipv4_packet (pkt, si, tos); 583 return send_ipv4_packet (pkt, si, tos);
522 584
523 case PROT_UDPv4: 585 case PROT_UDPv4:
524 return send_udpv4_packet (pkt, si, tos); 586 return send_udpv4_packet (pkt, si, tos);
525 587
526#if ENABLE_TCP 588#if ENABLE_TCP
527 case PROT_TCPv4: 589 case PROT_TCPv4:
528 return send_tcpv4_packet (pkt, si, tos); 590 return send_tcpv4_packet (pkt, si, tos);
529#endif 591#endif
530#if ENABLE_ICMP 592#if ENABLE_ICMP
531 case PROT_ICMPv4: 593 case PROT_ICMPv4:
532 return send_icmpv4_packet (pkt, si, tos); 594 return send_icmpv4_packet (pkt, si, tos);
533#endif 595#endif
534#if ENABLE_DNS 596#if ENABLE_DNS
535 case PROT_DNSv4: 597 case PROT_DNSv4:
536 return send_dnsv4_packet (pkt, si, tos); 598 return send_dnsv4_packet (pkt, si, tos);
537#endif 599#endif
538 default: 600 default:
539 slog (L_CRIT, _("%s: FATAL: trying to send packet with unsupported protocol."), (const char *)si); 601 slog (L_CRIT, _("%s: FATAL: trying to send packet with unsupported protocol."), (const char *)si);
540 } 602 }
541 603
559 if (len > 0) 621 if (len > 0)
560 { 622 {
561 pkt->len = len; 623 pkt->len = len;
562 624
563 // raw sockets deliver the ipv4 header, but don't expect it on sends 625 // raw sockets deliver the ipv4 header, but don't expect it on sends
564 pkt->skip_ipv4_hdr (); 626 pkt->skip_hdr (pkt->ipv4_hdr_len ());
565 627
566 recv_vpn_packet (pkt, si); 628 recv_vpn_packet (pkt, si);
567 } 629 }
568 else 630 else
569 { 631 {
606 if (hdr->type == ::conf.icmp_type 668 if (hdr->type == ::conf.icmp_type
607 && hdr->code == 255) 669 && hdr->code == 255)
608 { 670 {
609 // raw sockets deliver the ipv4, but don't expect it on sends 671 // raw sockets deliver the ipv4, but don't expect it on sends
610 // this is slow, but... 672 // this is slow, but...
611 pkt->skip_ipv4_hdr (ICMP_OVERHEAD - IP_OVERHEAD); 673 pkt->skip_hdr (pkt->ipv4_hdr_len () + (ICMP_OVERHEAD - IP_OVERHEAD));
612 674
613 recv_vpn_packet (pkt, si); 675 recv_vpn_packet (pkt, si);
614 } 676 }
615 } 677 }
616 else 678 else

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines