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.22 by pcg, Thu Oct 16 02:41:21 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 (%d <=> %d)"), prot_major, PROTOCOL_MAJOR);
482 && hmaclen == HMACLENGTH 485 else if (randsize != RAND_SIZE)
483 && flags == curflags () 486 slog (L_WARN, _("rand size mismatch (%d <=> %d)"), randsize, RAND_SIZE);
487 else if (hmaclen != HMACLENGTH)
488 slog (L_WARN, _("hmac length mismatch (%d <=> %d)"), hmaclen, HMACLENGTH);
489 else if (flags != curflags ())
490 slog (L_WARN, _("flag mismatch (%x <=> %x)"), flags, curflags ());
484 && challengelen == sizeof (rsachallenge) 491 else if (challengelen != sizeof (rsachallenge))
492 slog (L_WARN, _("challenge length mismatch (%d <=> %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 (%x <=> %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 (%x <=> %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 (%x <=> %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))
903 slog (L_ERR, _("%s(%s): challenge illegal or corrupted"), 916 slog (L_ERR, _("%s(%s): challenge illegal or corrupted (%s). mismatched key or config file?"),
904 conf->nodename, (const char *)rsi); 917 conf->nodename, (const char *)rsi, ERR_error_string (ERR_get_error (), 0));
905 else 918 else
906 { 919 {
907 delete octx; 920 delete octx;
908 921
909 octx = new crypto_ctx (k, 1); 922 octx = new crypto_ctx (k, 1);
916 connection_established (); 929 connection_established ();
917 930
918 break; 931 break;
919 } 932 }
920 } 933 }
934 else
935 slog (L_WARN, _("%s(%s): protocol mismatch"),
936 conf->nodename, (const char *)rsi);
921 937
922 send_reset (rsi); 938 send_reset (rsi);
923 } 939 }
924 940
925 break; 941 break;
939 955
940 rsachallenge chg; 956 rsachallenge chg;
941 957
942 if (!rsa_cache.find (p->id, chg)) 958 if (!rsa_cache.find (p->id, chg))
943 { 959 {
944 slog (L_ERR, _("%s(%s): unrequested auth response"), 960 slog (L_ERR, _("%s(%s): unrequested auth response ignored"),
945 conf->nodename, (const char *)rsi); 961 conf->nodename, (const char *)rsi);
946 break; 962 break;
947 } 963 }
948 else 964 else
949 { 965 {
950 crypto_ctx *cctx = new crypto_ctx (chg, 0); 966 crypto_ctx *cctx = new crypto_ctx (chg, 0);
951 967
952 if (!p->hmac_chk (cctx)) 968 if (!p->hmac_chk (cctx))
969 {
953 slog (L_ERR, _("%s(%s): hmac authentication error on auth response, received invalid packet\n" 970 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"), 971 "could be an attack, or just corruption or an synchronization error"),
955 conf->nodename, (const char *)rsi); 972 conf->nodename, (const char *)rsi);
973 break;
974 }
956 else 975 else
957 { 976 {
958 rsaresponse h; 977 rsaresponse h;
959 978
960 rsa_hash (p->id, chg, h); 979 rsa_hash (p->id, chg, h);
1017 1036
1018 if (iseqno.recv_ok (seqno)) 1037 if (iseqno.recv_ok (seqno))
1019 { 1038 {
1020 vpn->tap->send (d); 1039 vpn->tap->send (d);
1021 1040
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) 1041 if (si != rsi)
1032 { 1042 {
1033 // fast re-sync on conneciton changes, useful especially for tcp/ip 1043 // fast re-sync on connection changes, useful especially for tcp/ip
1034 si = rsi; 1044 si = rsi;
1035 1045
1036 slog (L_INFO, _("%s(%s): socket address changed to %s"), 1046 slog (L_INFO, _("%s(%s): socket address changed to %s"),
1037 conf->nodename, (const char *)si, (const char *)rsi); 1047 conf->nodename, (const char *)si, (const char *)rsi);
1038 } 1048 }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines