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

Comparing gvpe/src/protocol.C (file contents):
Revision 1.17 by pcg, Wed Mar 26 01:58:46 2003 UTC vs.
Revision 1.20 by pcg, Wed Mar 26 17:59:12 2003 UTC

82 EVP_CIPHER_CTX_cleanup (&cctx); 82 EVP_CIPHER_CTX_cleanup (&cctx);
83 HMAC_CTX_cleanup (&hctx); 83 HMAC_CTX_cleanup (&hctx);
84} 84}
85 85
86static void 86static void
87rsa_hash (const rsachallenge &chg, rsaresponse &h) 87rsa_hash (const rsaid &id, const rsachallenge &chg, rsaresponse &h)
88{ 88{
89 EVP_MD_CTX ctx; 89 EVP_MD_CTX ctx;
90 90
91 EVP_MD_CTX_init (&ctx); 91 EVP_MD_CTX_init (&ctx);
92 EVP_DigestInit (&ctx, RSA_HASH); 92 EVP_DigestInit (&ctx, RSA_HASH);
93 EVP_DigestUpdate(&ctx, &chg, sizeof chg); 93 EVP_DigestUpdate(&ctx, &chg, sizeof chg);
94 EVP_DigestUpdate(&ctx, &id, sizeof id);
94 EVP_DigestFinal (&ctx, (unsigned char *)&h, 0); 95 EVP_DigestFinal (&ctx, (unsigned char *)&h, 0);
95 EVP_MD_CTX_cleanup (&ctx); 96 EVP_MD_CTX_cleanup (&ctx);
96} 97}
97 98
98struct rsa_entry { 99struct rsa_entry {
289 bool send = ri.diff / ri.pcnt > CUTOFF; 290 bool send = ri.diff / ri.pcnt > CUTOFF;
290 291
291 if (send) 292 if (send)
292 ri.pcnt++; 293 ri.pcnt++;
293 294
294 //printf ("RATE %d %f,%f = %f > %f\n", !!send, ri.pcnt, ri.diff, ri.diff / ri.pcnt, CUTOFF);
295
296 push_front (ri); 295 push_front (ri);
297 296
298 return send; 297 return send;
299 } 298 }
300} 299}
308} 307}
309 308
310static unsigned char hmac_digest[EVP_MAX_MD_SIZE]; 309static unsigned char hmac_digest[EVP_MAX_MD_SIZE];
311 310
312struct hmac_packet:net_packet 311struct hmac_packet:net_packet
312{
313 u8 hmac[HMACLENGTH]; // each and every packet has a hmac field, but that is not (yet) checked everywhere
314
315 void hmac_set (crypto_ctx * ctx);
316 bool hmac_chk (crypto_ctx * ctx);
317
318private:
319 void hmac_gen (crypto_ctx * ctx)
313 { 320 {
314 u8 hmac[HMACLENGTH]; // each and every packet has a hmac field, but that is not (yet) checked everywhere
315
316 void hmac_set (crypto_ctx * ctx);
317 bool hmac_chk (crypto_ctx * ctx);
318
319private:
320 void hmac_gen (crypto_ctx * ctx)
321 {
322 unsigned int xlen; 321 unsigned int xlen;
323 HMAC_CTX *hctx = &ctx->hctx; 322 HMAC_CTX *hctx = &ctx->hctx;
324 323
325 HMAC_Init_ex (hctx, 0, 0, 0, 0); 324 HMAC_Init_ex (hctx, 0, 0, 0, 0);
326 HMAC_Update (hctx, ((unsigned char *) this) + sizeof (hmac_packet), 325 HMAC_Update (hctx, ((unsigned char *) this) + sizeof (hmac_packet),
327 len - sizeof (hmac_packet)); 326 len - sizeof (hmac_packet));
328 HMAC_Final (hctx, (unsigned char *) &hmac_digest, &xlen); 327 HMAC_Final (hctx, (unsigned char *) &hmac_digest, &xlen);
329 }
330 }; 328 }
329};
331 330
332void 331void
333hmac_packet::hmac_set (crypto_ctx * ctx) 332hmac_packet::hmac_set (crypto_ctx * ctx)
334{ 333{
335 hmac_gen (ctx); 334 hmac_gen (ctx);
502 501
503#if ENABLE_COMPRESSION 502#if ENABLE_COMPRESSION
504 if (type == PT_DATA_COMPRESSED) 503 if (type == PT_DATA_COMPRESSED)
505 { 504 {
506 u32 cl = (d[DATAHDR] << 8) | d[DATAHDR + 1]; 505 u32 cl = (d[DATAHDR] << 8) | d[DATAHDR + 1];
506
507 p->len = lzf_decompress (d + DATAHDR + 2, cl, &(*p)[6 + 6], MAX_MTU) + 6 + 6; 507 p->len = lzf_decompress (d + DATAHDR + 2, cl < MAX_MTU ? cl : 0,
508 &(*p)[6 + 6], MAX_MTU)
509 + 6 + 6;
508 } 510 }
509 else 511 else
510 p->len = outl + (6 + 6 - DATAHDR); 512 p->len = outl + (6 + 6 - DATAHDR);
511#endif 513#endif
512 514
585}; 587};
586 588
587struct auth_res_packet : config_packet 589struct auth_res_packet : config_packet
588{ 590{
589 rsaid id; 591 rsaid id;
592 u8 pad1, pad2, pad3;
593 u8 response_len; // encrypted length
590 rsaresponse response; 594 rsaresponse response;
591 595
592 auth_res_packet (int dst) 596 auth_res_packet (int dst)
593 { 597 {
594 config_packet::setup (PT_AUTH_RES, dst); 598 config_packet::setup (PT_AUTH_RES, dst);
680} 684}
681 685
682void 686void
683connection::send_auth_request (SOCKADDR *sa, bool initiate) 687connection::send_auth_request (SOCKADDR *sa, bool initiate)
684{ 688{
685 if (auth_rate_limiter.can (sa)) 689 if (!initiate || auth_rate_limiter.can (sa))
686 { 690 {
687 auth_req_packet *pkt = new auth_req_packet (conf->id, initiate); 691 auth_req_packet *pkt = new auth_req_packet (conf->id, initiate);
688 692
689 rsachallenge chg; 693 rsachallenge chg;
690 694
704} 708}
705 709
706void 710void
707connection::send_auth_response (SOCKADDR *sa, const rsaid &id, const rsachallenge &chg) 711connection::send_auth_response (SOCKADDR *sa, const rsaid &id, const rsachallenge &chg)
708{ 712{
709 if (auth_rate_limiter.can (sa))
710 {
711 auth_res_packet *pkt = new auth_res_packet (conf->id); 713 auth_res_packet *pkt = new auth_res_packet (conf->id);
712 714
713 pkt->id = id; 715 pkt->id = id;
716
714 rsa_hash (chg, pkt->response); 717 rsa_hash (id, chg, pkt->response);
715 718
719 pkt->hmac_set (octx);
720
716 slog (L_TRACE, ">>%d PT_AUTH_RES [%s]", conf->id, (const char *)sockinfo (sa)); 721 slog (L_TRACE, ">>%d PT_AUTH_RES [%s]", conf->id, (const char *)sockinfo (sa));
717 722
718 vpn->send_vpn_packet (pkt, sa, IPTOS_RELIABILITY); // rsa is very very costly 723 vpn->send_vpn_packet (pkt, sa, IPTOS_RELIABILITY); // rsa is very very costly
719 724
720 delete pkt; 725 delete pkt;
721 }
722} 726}
723 727
724void 728void
725connection::establish_connection_cb (tstamp &ts) 729connection::establish_connection_cb (tstamp &ts)
726{ 730{
727 if (ictx || conf == THISNODE || connectmode == conf_node::C_NEVER) 731 if (ictx || conf == THISNODE
732 || connectmode == conf_node::C_NEVER
733 || connectmode == conf_node::C_DISABLED)
728 ts = TSTAMP_CANCEL; 734 ts = TSTAMP_CANCEL;
729 else if (ts <= NOW) 735 else if (ts <= NOW)
730 { 736 {
731 double retry_int = double (retry_cnt & 3 ? (retry_cnt & 3) : 1 << (retry_cnt >> 2)) * 0.6; 737 double retry_int = double (retry_cnt & 3 ? (retry_cnt & 3) : 1 << (retry_cnt >> 2)) * 0.6;
732 738
752void 758void
753connection::reset_connection () 759connection::reset_connection ()
754{ 760{
755 if (ictx && octx) 761 if (ictx && octx)
756 { 762 {
757 slog (L_INFO, _("connection to %d (%s) lost"), conf->id, conf->nodename); 763 slog (L_INFO, _("%s(%s): connection lost"),
764 conf->nodename, (const char *)sockinfo (sa));
758 765
759 if (::conf.script_node_down) 766 if (::conf.script_node_down)
760 run_script (run_script_cb (this, &connection::script_node_down), false); 767 run_script (run_script_cb (this, &connection::script_node_down), false);
761 } 768 }
762 769
859 866
860 config_packet *p = (config_packet *) pkt; 867 config_packet *p = (config_packet *) pkt;
861 868
862 if (!p->chk_config ()) 869 if (!p->chk_config ())
863 { 870 {
864 slog (L_WARN, _("protocol mismatch, disabling node '%s'"), conf->nodename); 871 slog (L_WARN, _("%s(%s): protocol mismatch, disabling node"),
872 conf->nodename, (const char *)sockinfo (ssa));
865 connectmode = conf_node::C_DISABLED; 873 connectmode = conf_node::C_DISABLED;
866 } 874 }
867 else if (connectmode == conf_node::C_ALWAYS) 875 else if (connectmode == conf_node::C_ALWAYS)
868 establish_connection (); 876 establish_connection ();
869 } 877 }
870 break; 878 break;
871 879
872 case vpn_packet::PT_AUTH_REQ: 880 case vpn_packet::PT_AUTH_REQ:
881 if (auth_rate_limiter.can (ssa))
882 {
883 auth_req_packet *p = (auth_req_packet *) pkt;
884
885 slog (L_TRACE, "<<%d PT_AUTH_REQ(%d)", conf->id, p->initiate);
886
887 if (p->chk_config () && !strncmp (p->magic, MAGIC, 8))
888 {
889 if (p->prot_minor != PROTOCOL_MINOR)
890 slog (L_INFO, _("%s(%s): protocol minor version mismatch: ours is %d, %s's is %d."),
891 conf->nodename, (const char *)sockinfo (ssa),
892 PROTOCOL_MINOR, conf->nodename, p->prot_minor);
893
894 if (p->initiate)
895 send_auth_request (ssa, false);
896
897 rsachallenge k;
898
899 if (0 > RSA_private_decrypt (sizeof (p->encr),
900 (unsigned char *)&p->encr, (unsigned char *)&k,
901 ::conf.rsa_key, RSA_PKCS1_OAEP_PADDING))
902 slog (L_ERR, _("%s(%s): challenge illegal or corrupted"),
903 conf->nodename, (const char *)sockinfo (ssa));
904 else
905 {
906 retry_cnt = 0;
907 establish_connection.set (NOW + 8); //? ;)
908 keepalive.reset ();
909 rekey.reset ();
910
911 delete ictx;
912 ictx = 0;
913
914 delete octx;
915
916 octx = new crypto_ctx (k, 1);
917 oseqno = ntohl (*(u32 *)&k[CHG_SEQNO]) & 0x7fffffff;
918
919 send_auth_response (ssa, p->id, k);
920
921 break;
922 }
923 }
924
925 send_reset (ssa);
926 }
927
928 break;
929
930 case vpn_packet::PT_AUTH_RES:
873 { 931 {
874 auth_req_packet *p = (auth_req_packet *) pkt; 932 auth_res_packet *p = (auth_res_packet *) pkt;
875 933
876 slog (L_TRACE, "<<%d PT_AUTH_REQ(%d)", conf->id, p->initiate); 934 slog (L_TRACE, "<<%d PT_AUTH_RES", conf->id);
877 935
878 if (p->chk_config () && !strncmp (p->magic, MAGIC, 8)) 936 if (p->chk_config ())
879 { 937 {
880 if (p->prot_minor != PROTOCOL_MINOR) 938 if (p->prot_minor != PROTOCOL_MINOR)
881 slog (L_INFO, _("protocol minor version mismatch: ours is %d, %s's is %d."), 939 slog (L_INFO, _("%s(%s): protocol minor version mismatch: ours is %d, %s's is %d."),
940 conf->nodename, (const char *)sockinfo (ssa),
882 PROTOCOL_MINOR, conf->nodename, p->prot_minor); 941 PROTOCOL_MINOR, conf->nodename, p->prot_minor);
883 942
884 if (p->initiate)
885 send_auth_request (ssa, false);
886
887 rsachallenge k; 943 rsachallenge chg;
888 944
889 if (0 > RSA_private_decrypt (sizeof (p->encr), 945 if (!rsa_cache.find (p->id, chg))
890 (unsigned char *)&p->encr, (unsigned char *)&k, 946 slog (L_ERR, _("%s(%s): unrequested auth response"),
891 ::conf.rsa_key, RSA_PKCS1_OAEP_PADDING))
892 slog (L_ERR, _("challenge from %s (%s) illegal or corrupted"),
893 conf->nodename, (const char *)sockinfo (ssa)); 947 conf->nodename, (const char *)sockinfo (ssa));
894 else 948 else
895 { 949 {
896 retry_cnt = 0; 950 crypto_ctx *cctx = new crypto_ctx (chg, 0);
897 establish_connection.set (NOW + 8); //? ;)
898 keepalive.reset ();
899 rekey.reset ();
900 951
901 delete ictx; 952 if (!p->hmac_chk (cctx))
902 ictx = 0; 953 slog (L_ERR, _("%s(%s): hmac authentication error on auth response, received invalid packet\n"
903 954 "could be an attack, or just corruption or an synchronization error"),
904 delete octx;
905
906 octx = new crypto_ctx (k, 1);
907 oseqno = ntohl (*(u32 *)&k[CHG_SEQNO]) & 0x7fffffff;
908
909 send_auth_response (ssa, p->id, k);
910
911 break;
912 }
913 }
914
915
916 }
917
918 send_reset (ssa);
919 break;
920
921 case vpn_packet::PT_AUTH_RES:
922 {
923 auth_res_packet *p = (auth_res_packet *) pkt;
924
925 slog (L_TRACE, "<<%d PT_AUTH_RES", conf->id);
926
927 if (p->chk_config ())
928 {
929 if (p->prot_minor != PROTOCOL_MINOR)
930 slog (L_INFO, _("protocol minor version mismatch: ours is %d, %s's is %d."),
931 PROTOCOL_MINOR, conf->nodename, p->prot_minor);
932
933 rsachallenge chg;
934
935 if (!rsa_cache.find (p->id, chg))
936 slog (L_ERR, _("unrequested auth response from %s (%s)"),
937 conf->nodename, (const char *)sockinfo (ssa)); 955 conf->nodename, (const char *)sockinfo (ssa));
938 else 956 else
939 {
940 rsaresponse h;
941
942 rsa_hash (chg, h);
943
944 if (!memcmp ((u8 *)&h, (u8 *)p->response, sizeof h))
945 { 957 {
946 delete ictx;
947
948 ictx = new crypto_ctx (chg, 0);
949 iseqno.reset (ntohl (*(u32 *)&chg[CHG_SEQNO]) & 0x7fffffff); // at least 2**31 sequence numbers are valid
950
951 sa = *ssa; 958 rsaresponse h;
952 959
953 rekey.set (NOW + ::conf.rekey); 960 rsa_hash (p->id, chg, h);
954 keepalive.set (NOW + ::conf.keepalive);
955 961
956 // send queued packets 962 if (!memcmp ((u8 *)&h, (u8 *)p->response, sizeof h))
957 while (tap_packet *p = queue.get ())
958 { 963 {
964 prot_minor = p->prot_minor;
965
966 delete ictx; ictx = cctx;
967
968 iseqno.reset (ntohl (*(u32 *)&chg[CHG_SEQNO]) & 0x7fffffff); // at least 2**31 sequence numbers are valid
969
970 sa = *ssa;
971
972 rekey.set (NOW + ::conf.rekey);
973 keepalive.set (NOW + ::conf.keepalive);
974
975 // send queued packets
976 while (tap_packet *p = queue.get ())
977 {
959 send_data_packet (p); 978 send_data_packet (p);
960 delete p; 979 delete p;
980 }
981
982 connectmode = conf->connectmode;
983
984 slog (L_INFO, _("%s(%s): connection established, protocol version %d.%d"),
985 conf->nodename, (const char *)sockinfo (ssa),
986 p->prot_major, p->prot_minor);
987
988 if (::conf.script_node_up)
989 run_script (run_script_cb (this, &connection::script_node_up), false);
990
991 break;
961 } 992 }
962 993 else
963 connectmode = conf->connectmode; 994 slog (L_ERR, _("%s(%s): sent and received challenge do not match"),
964
965 slog (L_INFO, _("connection to %d (%s %s) established"),
966 conf->id, conf->nodename, (const char *)sockinfo (ssa)); 995 conf->nodename, (const char *)sockinfo (ssa));
967
968 if (::conf.script_node_up)
969 run_script (run_script_cb (this, &connection::script_node_up), false);
970
971 break;
972 } 996 }
997
973 else 998 delete cctx;
974 slog (L_ERR, _("sent and received challenge do not match with (%s %s))"),
975 conf->nodename, (const char *)sockinfo (ssa));
976 } 999 }
977 } 1000 }
978 } 1001 }
979 1002
980 send_reset (ssa); 1003 send_reset (ssa);
993 vpndata_packet *p = (vpndata_packet *)pkt; 1016 vpndata_packet *p = (vpndata_packet *)pkt;
994 1017
995 if (*ssa == sa) 1018 if (*ssa == sa)
996 { 1019 {
997 if (!p->hmac_chk (ictx)) 1020 if (!p->hmac_chk (ictx))
998 slog (L_ERR, _("hmac authentication error, received invalid packet\n" 1021 slog (L_ERR, _("%s(%s): hmac authentication error, received invalid packet\n"
999 "could be an attack, or just corruption or an synchronization error")); 1022 "could be an attack, or just corruption or an synchronization error"),
1023 conf->nodename, (const char *)sockinfo (ssa));
1000 else 1024 else
1001 { 1025 {
1002 u32 seqno; 1026 u32 seqno;
1003 tap_packet *d = p->unpack (this, seqno); 1027 tap_packet *d = p->unpack (this, seqno);
1004 1028

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines