… | |
… | |
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 | |
86 | static void |
86 | static void |
87 | rsa_hash (const rsachallenge &chg, rsaresponse &h) |
87 | rsa_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 | |
98 | struct rsa_entry { |
99 | struct rsa_entry { |
… | |
… | |
500 | |
501 | |
501 | #if ENABLE_COMPRESSION |
502 | #if ENABLE_COMPRESSION |
502 | if (type == PT_DATA_COMPRESSED) |
503 | if (type == PT_DATA_COMPRESSED) |
503 | { |
504 | { |
504 | u32 cl = (d[DATAHDR] << 8) | d[DATAHDR + 1]; |
505 | u32 cl = (d[DATAHDR] << 8) | d[DATAHDR + 1]; |
|
|
506 | |
505 | 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; |
506 | } |
510 | } |
507 | else |
511 | else |
508 | p->len = outl + (6 + 6 - DATAHDR); |
512 | p->len = outl + (6 + 6 - DATAHDR); |
509 | #endif |
513 | #endif |
510 | |
514 | |
… | |
… | |
583 | }; |
587 | }; |
584 | |
588 | |
585 | struct auth_res_packet : config_packet |
589 | struct auth_res_packet : config_packet |
586 | { |
590 | { |
587 | rsaid id; |
591 | rsaid id; |
|
|
592 | u8 pad1, pad2, pad3; |
|
|
593 | u8 response_len; // encrypted length |
588 | rsaresponse response; |
594 | rsaresponse response; |
589 | |
595 | |
590 | auth_res_packet (int dst) |
596 | auth_res_packet (int dst) |
591 | { |
597 | { |
592 | config_packet::setup (PT_AUTH_RES, dst); |
598 | config_packet::setup (PT_AUTH_RES, dst); |
… | |
… | |
678 | } |
684 | } |
679 | |
685 | |
680 | void |
686 | void |
681 | connection::send_auth_request (SOCKADDR *sa, bool initiate) |
687 | connection::send_auth_request (SOCKADDR *sa, bool initiate) |
682 | { |
688 | { |
683 | if (auth_rate_limiter.can (sa)) |
689 | if (!initiate || auth_rate_limiter.can (sa)) |
684 | { |
690 | { |
685 | auth_req_packet *pkt = new auth_req_packet (conf->id, initiate); |
691 | auth_req_packet *pkt = new auth_req_packet (conf->id, initiate); |
686 | |
692 | |
687 | rsachallenge chg; |
693 | rsachallenge chg; |
688 | |
694 | |
… | |
… | |
702 | } |
708 | } |
703 | |
709 | |
704 | void |
710 | void |
705 | connection::send_auth_response (SOCKADDR *sa, const rsaid &id, const rsachallenge &chg) |
711 | connection::send_auth_response (SOCKADDR *sa, const rsaid &id, const rsachallenge &chg) |
706 | { |
712 | { |
707 | if (auth_rate_limiter.can (sa)) |
|
|
708 | { |
|
|
709 | auth_res_packet *pkt = new auth_res_packet (conf->id); |
713 | auth_res_packet *pkt = new auth_res_packet (conf->id); |
710 | |
714 | |
711 | pkt->id = id; |
715 | pkt->id = id; |
|
|
716 | |
712 | rsa_hash (chg, pkt->response); |
717 | rsa_hash (id, chg, pkt->response); |
713 | |
718 | |
|
|
719 | pkt->hmac_set (octx); |
|
|
720 | |
714 | 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)); |
715 | |
722 | |
716 | 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 |
717 | |
724 | |
718 | delete pkt; |
725 | delete pkt; |
719 | } |
|
|
720 | } |
726 | } |
721 | |
727 | |
722 | void |
728 | void |
723 | connection::establish_connection_cb (tstamp &ts) |
729 | connection::establish_connection_cb (tstamp &ts) |
724 | { |
730 | { |
… | |
… | |
752 | void |
758 | void |
753 | connection::reset_connection () |
759 | connection::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 | send_reset (ssa); |
|
|
917 | break; |
|
|
918 | |
|
|
919 | case vpn_packet::PT_AUTH_RES: |
|
|
920 | { |
|
|
921 | auth_res_packet *p = (auth_res_packet *) pkt; |
|
|
922 | |
|
|
923 | slog (L_TRACE, "<<%d PT_AUTH_RES", conf->id); |
|
|
924 | |
|
|
925 | if (p->chk_config ()) |
|
|
926 | { |
|
|
927 | if (p->prot_minor != PROTOCOL_MINOR) |
|
|
928 | slog (L_INFO, _("protocol minor version mismatch: ours is %d, %s's is %d."), |
|
|
929 | PROTOCOL_MINOR, conf->nodename, p->prot_minor); |
|
|
930 | |
|
|
931 | rsachallenge chg; |
|
|
932 | |
|
|
933 | if (!rsa_cache.find (p->id, chg)) |
|
|
934 | slog (L_ERR, _("unrequested auth response from %s (%s)"), |
|
|
935 | conf->nodename, (const char *)sockinfo (ssa)); |
955 | conf->nodename, (const char *)sockinfo (ssa)); |
936 | else |
956 | else |
937 | { |
|
|
938 | rsaresponse h; |
|
|
939 | |
|
|
940 | rsa_hash (chg, h); |
|
|
941 | |
|
|
942 | if (!memcmp ((u8 *)&h, (u8 *)p->response, sizeof h)) |
|
|
943 | { |
957 | { |
944 | delete ictx; |
|
|
945 | |
|
|
946 | ictx = new crypto_ctx (chg, 0); |
|
|
947 | iseqno.reset (ntohl (*(u32 *)&chg[CHG_SEQNO]) & 0x7fffffff); // at least 2**31 sequence numbers are valid |
|
|
948 | |
|
|
949 | sa = *ssa; |
958 | rsaresponse h; |
950 | |
959 | |
951 | rekey.set (NOW + ::conf.rekey); |
960 | rsa_hash (p->id, chg, h); |
952 | keepalive.set (NOW + ::conf.keepalive); |
|
|
953 | |
961 | |
954 | // send queued packets |
962 | if (!memcmp ((u8 *)&h, (u8 *)p->response, sizeof h)) |
955 | while (tap_packet *p = queue.get ()) |
|
|
956 | { |
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 | { |
957 | send_data_packet (p); |
978 | send_data_packet (p); |
958 | 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; |
959 | } |
992 | } |
960 | |
993 | else |
961 | connectmode = conf->connectmode; |
994 | slog (L_ERR, _("%s(%s): sent and received challenge do not match"), |
962 | |
|
|
963 | slog (L_INFO, _("connection to %d (%s %s) established"), |
|
|
964 | conf->id, conf->nodename, (const char *)sockinfo (ssa)); |
995 | conf->nodename, (const char *)sockinfo (ssa)); |
965 | |
|
|
966 | if (::conf.script_node_up) |
|
|
967 | run_script (run_script_cb (this, &connection::script_node_up), false); |
|
|
968 | |
|
|
969 | break; |
|
|
970 | } |
996 | } |
|
|
997 | |
971 | else |
998 | delete cctx; |
972 | slog (L_ERR, _("sent and received challenge do not match with (%s %s))"), |
|
|
973 | conf->nodename, (const char *)sockinfo (ssa)); |
|
|
974 | } |
999 | } |
975 | } |
1000 | } |
976 | } |
1001 | } |
977 | |
1002 | |
978 | send_reset (ssa); |
1003 | send_reset (ssa); |
… | |
… | |
991 | vpndata_packet *p = (vpndata_packet *)pkt; |
1016 | vpndata_packet *p = (vpndata_packet *)pkt; |
992 | |
1017 | |
993 | if (*ssa == sa) |
1018 | if (*ssa == sa) |
994 | { |
1019 | { |
995 | if (!p->hmac_chk (ictx)) |
1020 | if (!p->hmac_chk (ictx)) |
996 | slog (L_ERR, _("hmac authentication error, received invalid packet\n" |
1021 | slog (L_ERR, _("%s(%s): hmac authentication error, received invalid packet\n" |
997 | "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)); |
998 | else |
1024 | else |
999 | { |
1025 | { |
1000 | u32 seqno; |
1026 | u32 seqno; |
1001 | tap_packet *d = p->unpack (this, seqno); |
1027 | tap_packet *d = p->unpack (this, seqno); |
1002 | |
1028 | |