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

Comparing gvpe/src/connection.C (file contents):
Revision 1.13 by pcg, Fri Aug 8 07:52:26 2003 UTC vs.
Revision 1.24 by pcg, Wed Oct 22 01:05:23 2003 UTC

1/* 1/*
2 connection.C -- manage a single connection 2 connection.C -- manage a single connection
3 Copyright (C) 2003 Marc Lehmann <pcg@goof.com>
3 4
4 This program is free software; you can redistribute it and/or modify 5 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by 6 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or 7 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version. 8 (at your option) any later version.
35#include "slog.h" 36#include "slog.h"
36#include "device.h" 37#include "device.h"
37#include "vpn.h" 38#include "vpn.h"
38#include "connection.h" 39#include "connection.h"
39 40
41#include "netcompat.h"
42
40#if !HAVE_RAND_PSEUDO_BYTES 43#if !HAVE_RAND_PSEUDO_BYTES
41# define RAND_pseudo_bytes RAND_bytes 44# define RAND_pseudo_bytes RAND_bytes
42#endif 45#endif
43 46
44#define MAGIC "vped\xbd\xc6\xdb\x82" // 8 bytes of magic 47#define MAGIC "vped\xbd\xc6\xdb\x82" // 8 bytes of magic
197// only do action once every x seconds per host whole allowing bursts. 200// only do action once every x seconds per host whole allowing bursts.
198// this implementation ("splay list" ;) is inefficient, 201// this implementation ("splay list" ;) is inefficient,
199// but low on resources. 202// but low on resources.
200struct net_rate_limiter : list<net_rateinfo> 203struct net_rate_limiter : list<net_rateinfo>
201{ 204{
202 static const double ALPHA = 1. - 1. / 180.; // allow bursts 205 static const double ALPHA = 1. - 1. / 600.; // allow bursts
203 static const double CUTOFF = 10.; // one event every CUTOFF seconds 206 static const double CUTOFF = 10.; // one event every CUTOFF seconds
204 static const double EXPIRE = CUTOFF * 30.; // expire entries after this time 207 static const double EXPIRE = CUTOFF * 30.; // expire entries after this time
205 static const double MAXDIF = CUTOFF * (1. / (1. - ALPHA)); // maximum diff /count value 208 static const double MAXDIF = CUTOFF * (1. / (1. - ALPHA)); // maximum diff /count value
206 209
207 bool can (const sockinfo &si) { return can((u32)si.host); } 210 bool can (const sockinfo &si) { return can((u32)si.host); }
208 bool can (u32 host); 211 bool can (u32 host);
209}; 212};
210 213
211net_rate_limiter auth_rate_limiter, reset_rate_limiter; 214net_rate_limiter auth_rate_limiter, reset_rate_limiter;
212 215
475 set_hdr (type, dst); 478 set_hdr (type, dst);
476} 479}
477 480
478bool config_packet::chk_config () const 481bool config_packet::chk_config () const
479{ 482{
480 return prot_major == PROTOCOL_MAJOR 483 if (prot_major != PROTOCOL_MAJOR)
481 && randsize == RAND_SIZE 484 slog (L_WARN, _("major version mismatch (remote %d <=> local %d)"), prot_major, PROTOCOL_MAJOR);
482 && hmaclen == HMACLENGTH 485 else if (randsize != RAND_SIZE)
483 && flags == curflags () 486 slog (L_WARN, _("rand size mismatch (remote %d <=> local %d)"), randsize, RAND_SIZE);
487 else if (hmaclen != HMACLENGTH)
488 slog (L_WARN, _("hmac length mismatch (remote %d <=> local %d)"), hmaclen, HMACLENGTH);
489 else if (flags != curflags ())
490 slog (L_WARN, _("flag mismatch (remote %x <=> local %x)"), flags, curflags ());
484 && challengelen == sizeof (rsachallenge) 491 else if (challengelen != sizeof (rsachallenge))
492 slog (L_WARN, _("challenge length mismatch (remote %d <=> local %d)"), challengelen, sizeof (rsachallenge));
485 && cipher_nid == htonl (EVP_CIPHER_nid (CIPHER)) 493 else if (cipher_nid != htonl (EVP_CIPHER_nid (CIPHER)))
494 slog (L_WARN, _("cipher mismatch (remote %x <=> local %x)"), ntohl (cipher_nid), EVP_CIPHER_nid (CIPHER));
486 && digest_nid == htonl (EVP_MD_type (RSA_HASH)) 495 else if (digest_nid != htonl (EVP_MD_type (RSA_HASH)))
496 slog (L_WARN, _("digest mismatch (remote %x <=> local %x)"), ntohl (digest_nid), EVP_MD_type (RSA_HASH));
487 && hmac_nid == htonl (EVP_MD_type (DIGEST)); 497 else if (hmac_nid != htonl (EVP_MD_type (DIGEST)))
498 slog (L_WARN, _("hmac mismatch (remote %x <=> local %x)"), ntohl (hmac_nid), EVP_MD_type (DIGEST));
499 else
500 return true;
501
502 return false;
488} 503}
489 504
490struct auth_req_packet : config_packet 505struct auth_req_packet : config_packet
491{ 506{
492 char magic[8]; 507 char magic[8];
660connection::send_auth_request (const sockinfo &si, bool initiate) 675connection::send_auth_request (const sockinfo &si, bool initiate)
661{ 676{
662 auth_req_packet *pkt = new auth_req_packet (conf->id, initiate, THISNODE->protocols); 677 auth_req_packet *pkt = new auth_req_packet (conf->id, initiate, THISNODE->protocols);
663 678
664 rsachallenge chg; 679 rsachallenge chg;
665
666 rsa_cache.gen (pkt->id, chg); 680 rsa_cache.gen (pkt->id, chg);
667 681 rsa_encrypt (conf->rsa_key, chg, pkt->encr);
668 if (0 > RSA_public_encrypt (sizeof chg,
669 (unsigned char *)&chg, (unsigned char *)&pkt->encr,
670 conf->rsa_key, RSA_PKCS1_OAEP_PADDING))
671 fatal ("RSA_public_encrypt error");
672 682
673 slog (L_TRACE, ">>%d PT_AUTH_REQ [%s]", conf->id, (const char *)si); 683 slog (L_TRACE, ">>%d PT_AUTH_REQ [%s]", conf->id, (const char *)si);
674 684
675 send_vpn_packet (pkt, si, IPTOS_RELIABILITY | IPTOS_LOWDELAY); // rsa is very very costly 685 send_vpn_packet (pkt, si, IPTOS_RELIABILITY | IPTOS_LOWDELAY); // rsa is very very costly
676 686
786 reset_connection (); 796 reset_connection ();
787 establish_connection (); 797 establish_connection ();
788} 798}
789 799
790void 800void
791connection::send_data_packet (tap_packet *pkt, bool broadcast) 801connection::send_data_packet (tap_packet *pkt)
792{ 802{
793 vpndata_packet *p = new vpndata_packet; 803 vpndata_packet *p = new vpndata_packet;
794 int tos = 0; 804 int tos = 0;
795 805
796 // I am not hilarious about peeking into packets, but so be it. 806 // I am not hilarious about peeking into packets, but so be it.
797 if (conf->inherit_tos 807 if (conf->inherit_tos && pkt->is_ipv4 ())
798 && (*pkt)[12] == 0x08 && (*pkt)[13] == 0x00 // IP
799 && ((*pkt)[14] & 0xf0) == 0x40) // IPv4
800 tos = (*pkt)[15] & IPTOS_TOS_MASK; 808 tos = (*pkt)[15] & IPTOS_TOS_MASK;
801 809
802 p->setup (this, broadcast ? 0 : conf->id, &((*pkt)[6 + 6]), pkt->len - 6 - 6, ++oseqno); // skip 2 macs 810 p->setup (this, conf->id, &((*pkt)[6 + 6]), pkt->len - 6 - 6, ++oseqno); // skip 2 macs
803 send_vpn_packet (p, si, tos); 811 send_vpn_packet (p, si, tos);
804 812
805 delete p; 813 delete p;
806 814
807 if (oseqno > MAX_SEQNO) 815 if (oseqno > MAX_SEQNO)
808 rekey (); 816 rekey ();
809} 817}
810 818
811void 819void
812connection::inject_data_packet (tap_packet *pkt, bool broadcast) 820connection::inject_data_packet (tap_packet *pkt, bool broadcast/*TODO DDD*/)
813{ 821{
814 if (ictx && octx) 822 if (ictx && octx)
815 send_data_packet (pkt, broadcast); 823 send_data_packet (pkt);
816 else 824 else
817 { 825 {
818 if (!broadcast)//DDDD 826 if (!broadcast)//DDDD
819 data_queue.put (new tap_packet (*pkt)); 827 data_queue.put (new tap_packet (*pkt));
820 828
895 if (p->initiate) 903 if (p->initiate)
896 send_auth_request (rsi, false); 904 send_auth_request (rsi, false);
897 905
898 rsachallenge k; 906 rsachallenge k;
899 907
900 if (0 > RSA_private_decrypt (sizeof (p->encr), 908 if (!rsa_decrypt (::conf.rsa_key, p->encr, k))
901 (unsigned char *)&p->encr, (unsigned char *)&k, 909 {
902 ::conf.rsa_key, RSA_PKCS1_OAEP_PADDING))
903 slog (L_ERR, _("%s(%s): challenge illegal or corrupted"), 910 slog (L_ERR, _("%s(%s): challenge illegal or corrupted (%s). mismatched key or config file?"),
904 conf->nodename, (const char *)rsi); 911 conf->nodename, (const char *)rsi, ERR_error_string (ERR_get_error (), 0));
912 break;
913 }
905 else 914 else
906 { 915 {
907 delete octx; 916 delete octx;
908 917
909 octx = new crypto_ctx (k, 1); 918 octx = new crypto_ctx (k, 1);
916 connection_established (); 925 connection_established ();
917 926
918 break; 927 break;
919 } 928 }
920 } 929 }
930 else
931 slog (L_WARN, _("%s(%s): protocol mismatch"),
932 conf->nodename, (const char *)rsi);
921 933
922 send_reset (rsi); 934 send_reset (rsi);
923 } 935 }
924 936
925 break; 937 break;
939 951
940 rsachallenge chg; 952 rsachallenge chg;
941 953
942 if (!rsa_cache.find (p->id, chg)) 954 if (!rsa_cache.find (p->id, chg))
943 { 955 {
944 slog (L_ERR, _("%s(%s): unrequested auth response"), 956 slog (L_ERR, _("%s(%s): unrequested auth response ignored"),
945 conf->nodename, (const char *)rsi); 957 conf->nodename, (const char *)rsi);
946 break; 958 break;
947 } 959 }
948 else 960 else
949 { 961 {
950 crypto_ctx *cctx = new crypto_ctx (chg, 0); 962 crypto_ctx *cctx = new crypto_ctx (chg, 0);
951 963
952 if (!p->hmac_chk (cctx)) 964 if (!p->hmac_chk (cctx))
965 {
953 slog (L_ERR, _("%s(%s): hmac authentication error on auth response, received invalid packet\n" 966 slog (L_ERR, _("%s(%s): hmac authentication error on auth response, received invalid packet\n"
954 "could be an attack, or just corruption or an synchronization error"), 967 "could be an attack, or just corruption or an synchronization error"),
955 conf->nodename, (const char *)rsi); 968 conf->nodename, (const char *)rsi);
969 break;
970 }
956 else 971 else
957 { 972 {
958 rsaresponse h; 973 rsaresponse h;
959 974
960 rsa_hash (p->id, chg, h); 975 rsa_hash (p->id, chg, h);
1017 1032
1018 if (iseqno.recv_ok (seqno)) 1033 if (iseqno.recv_ok (seqno))
1019 { 1034 {
1020 vpn->tap->send (d); 1035 vpn->tap->send (d);
1021 1036
1022 if (p->dst () == 0) // re-broadcast
1023 for (vpn::conns_vector::iterator i = vpn->conns.begin (); i != vpn->conns.end (); ++i)
1024 {
1025 connection *c = *i;
1026
1027 if (c->conf != THISNODE && c->conf != conf)
1028 c->inject_data_packet (d);
1029 }
1030
1031 if (si != rsi) 1037 if (si != rsi)
1032 { 1038 {
1033 // fast re-sync on conneciton changes, useful especially for tcp/ip 1039 // fast re-sync on connection changes, useful especially for tcp/ip
1034 si = rsi; 1040 si = rsi;
1035 1041
1036 slog (L_INFO, _("%s(%s): socket address changed to %s"), 1042 slog (L_INFO, _("%s(%s): socket address changed to %s"),
1037 conf->nodename, (const char *)si, (const char *)rsi); 1043 conf->nodename, (const char *)si, (const char *)rsi);
1038 } 1044 }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines