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.23 by pcg, Wed Oct 22 00:42:53 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];
786 reset_connection (); 801 reset_connection ();
787 establish_connection (); 802 establish_connection ();
788} 803}
789 804
790void 805void
791connection::send_data_packet (tap_packet *pkt, bool broadcast) 806connection::send_data_packet (tap_packet *pkt)
792{ 807{
793 vpndata_packet *p = new vpndata_packet; 808 vpndata_packet *p = new vpndata_packet;
794 int tos = 0; 809 int tos = 0;
795 810
796 // I am not hilarious about peeking into packets, but so be it. 811 // I am not hilarious about peeking into packets, but so be it.
797 if (conf->inherit_tos 812 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; 813 tos = (*pkt)[15] & IPTOS_TOS_MASK;
801 814
802 p->setup (this, broadcast ? 0 : conf->id, &((*pkt)[6 + 6]), pkt->len - 6 - 6, ++oseqno); // skip 2 macs 815 p->setup (this, conf->id, &((*pkt)[6 + 6]), pkt->len - 6 - 6, ++oseqno); // skip 2 macs
803 send_vpn_packet (p, si, tos); 816 send_vpn_packet (p, si, tos);
804 817
805 delete p; 818 delete p;
806 819
807 if (oseqno > MAX_SEQNO) 820 if (oseqno > MAX_SEQNO)
808 rekey (); 821 rekey ();
809} 822}
810 823
811void 824void
812connection::inject_data_packet (tap_packet *pkt, bool broadcast) 825connection::inject_data_packet (tap_packet *pkt, bool broadcast/*TODO DDD*/)
813{ 826{
814 if (ictx && octx) 827 if (ictx && octx)
815 send_data_packet (pkt, broadcast); 828 send_data_packet (pkt);
816 else 829 else
817 { 830 {
818 if (!broadcast)//DDDD 831 if (!broadcast)//DDDD
819 data_queue.put (new tap_packet (*pkt)); 832 data_queue.put (new tap_packet (*pkt));
820 833
898 rsachallenge k; 911 rsachallenge k;
899 912
900 if (0 > RSA_private_decrypt (sizeof (p->encr), 913 if (0 > RSA_private_decrypt (sizeof (p->encr),
901 (unsigned char *)&p->encr, (unsigned char *)&k, 914 (unsigned char *)&p->encr, (unsigned char *)&k,
902 ::conf.rsa_key, RSA_PKCS1_OAEP_PADDING)) 915 ::conf.rsa_key, RSA_PKCS1_OAEP_PADDING))
916 {
903 slog (L_ERR, _("%s(%s): challenge illegal or corrupted"), 917 slog (L_ERR, _("%s(%s): challenge illegal or corrupted (%s). mismatched key or config file?"),
904 conf->nodename, (const char *)rsi); 918 conf->nodename, (const char *)rsi, ERR_error_string (ERR_get_error (), 0));
919 break;
920 }
905 else 921 else
906 { 922 {
907 delete octx; 923 delete octx;
908 924
909 octx = new crypto_ctx (k, 1); 925 octx = new crypto_ctx (k, 1);
916 connection_established (); 932 connection_established ();
917 933
918 break; 934 break;
919 } 935 }
920 } 936 }
937 else
938 slog (L_WARN, _("%s(%s): protocol mismatch"),
939 conf->nodename, (const char *)rsi);
921 940
922 send_reset (rsi); 941 send_reset (rsi);
923 } 942 }
924 943
925 break; 944 break;
939 958
940 rsachallenge chg; 959 rsachallenge chg;
941 960
942 if (!rsa_cache.find (p->id, chg)) 961 if (!rsa_cache.find (p->id, chg))
943 { 962 {
944 slog (L_ERR, _("%s(%s): unrequested auth response"), 963 slog (L_ERR, _("%s(%s): unrequested auth response ignored"),
945 conf->nodename, (const char *)rsi); 964 conf->nodename, (const char *)rsi);
946 break; 965 break;
947 } 966 }
948 else 967 else
949 { 968 {
950 crypto_ctx *cctx = new crypto_ctx (chg, 0); 969 crypto_ctx *cctx = new crypto_ctx (chg, 0);
951 970
952 if (!p->hmac_chk (cctx)) 971 if (!p->hmac_chk (cctx))
972 {
953 slog (L_ERR, _("%s(%s): hmac authentication error on auth response, received invalid packet\n" 973 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"), 974 "could be an attack, or just corruption or an synchronization error"),
955 conf->nodename, (const char *)rsi); 975 conf->nodename, (const char *)rsi);
976 break;
977 }
956 else 978 else
957 { 979 {
958 rsaresponse h; 980 rsaresponse h;
959 981
960 rsa_hash (p->id, chg, h); 982 rsa_hash (p->id, chg, h);
1017 1039
1018 if (iseqno.recv_ok (seqno)) 1040 if (iseqno.recv_ok (seqno))
1019 { 1041 {
1020 vpn->tap->send (d); 1042 vpn->tap->send (d);
1021 1043
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) 1044 if (si != rsi)
1032 { 1045 {
1033 // fast re-sync on conneciton changes, useful especially for tcp/ip 1046 // fast re-sync on connection changes, useful especially for tcp/ip
1034 si = rsi; 1047 si = rsi;
1035 1048
1036 slog (L_INFO, _("%s(%s): socket address changed to %s"), 1049 slog (L_INFO, _("%s(%s): socket address changed to %s"),
1037 conf->nodename, (const char *)si, (const char *)rsi); 1050 conf->nodename, (const char *)si, (const char *)rsi);
1038 } 1051 }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines