[vpnc-devel] svn commit: vpnc r310 - in /branches/vpnc-nortel: config.h isakmp-pkt.c isakmp-pkt.h sysdep.c tunip.c vpnc.c
vpnc at unix-ag.uni-kl.de
vpnc at unix-ag.uni-kl.de
Sun Jun 15 16:43:51 CEST 2008
Author: Joerg Mayer
Date: Sun Jun 15 16:43:50 2008
New Revision: 310
Log:
Merge some patches from trunk:
305: Add an unknown vendor id that is displayed as CWR in Cisco logs.
306: Make DEBUG... macros more readable.
Add a missing printf keyword in a DEBUG statement.
307: Add a reminder where to start when reverse engineering the firewall codes
of the ciscoclient.
308: Rename flatten_isakmp_payload to flatten_isakmp_payloads.
309: Memory leak fixes: The fixes are only in the non-Nortel
code paths!
Modified:
branches/vpnc-nortel/config.h
branches/vpnc-nortel/isakmp-pkt.c
branches/vpnc-nortel/isakmp-pkt.h
branches/vpnc-nortel/sysdep.c
branches/vpnc-nortel/tunip.c
branches/vpnc-nortel/vpnc.c
Modified: branches/vpnc-nortel/config.h
==============================================================================
--- branches/vpnc-nortel/config.h (original)
+++ branches/vpnc-nortel/config.h Sun Jun 15 16:43:50 2008
@@ -113,8 +113,21 @@
st; \
})
-#define DEBUGTOP(lvl, a) do {if(opt_debug >= (lvl)){ printf("\n");(a);printf(" [%s]\n", TIMESTAMP());}} while (0)
-#define DEBUG(lvl, a) do {if (opt_debug >= (lvl)) {if(opt_debug>1)printf(" "); a;}} while (0)
+#define DEBUGTOP(LVL, COMMAND) do { \
+ if (opt_debug >= (LVL)) { \
+ printf("\n"); \
+ COMMAND; \
+ printf(" [%s]\n", TIMESTAMP()); \
+ } \
+ } while (0)
+
+#define DEBUG(LVL, COMMAND) do { \
+ if (opt_debug >= (LVL)) { \
+ if (opt_debug > 1) \
+ printf(" "); \
+ COMMAND; \
+ } \
+ } while (0)
extern void hex_dump(const char *str, const void *data, ssize_t len, const struct debug_strings *decode);
extern void do_config(int argc, char **argv);
Modified: branches/vpnc-nortel/isakmp-pkt.c
==============================================================================
--- branches/vpnc-nortel/isakmp-pkt.c (original)
+++ branches/vpnc-nortel/isakmp-pkt.c Sun Jun 15 16:43:50 2008
@@ -230,13 +230,22 @@
flow_payload(f, p->next);
}
-void flatten_isakmp_payload(struct isakmp_payload *p, uint8_t ** result, size_t * size)
+void flatten_isakmp_payloads(struct isakmp_payload *p, uint8_t ** result, size_t * size)
{
struct flow f;
init_flow(&f);
flow_payload(&f, p);
*result = f.base;
*size = f.end - f.base;
+}
+
+void flatten_isakmp_payload(struct isakmp_payload *p, uint8_t ** result, size_t * size)
+{
+ struct isakmp_payload *next;
+ next = p->next;
+ p->next = NULL;
+ flatten_isakmp_payloads(p, result, size);
+ p->next = next;
}
void flatten_isakmp_packet(struct isakmp_packet *p, uint8_t ** result, size_t * size, size_t blksz)
Modified: branches/vpnc-nortel/isakmp-pkt.h
==============================================================================
--- branches/vpnc-nortel/isakmp-pkt.h (original)
+++ branches/vpnc-nortel/isakmp-pkt.h Sun Jun 15 16:43:50 2008
@@ -140,6 +140,7 @@
extern struct isakmp_attribute *dup_isakmp_attributes(struct isakmp_attribute *);
extern void free_isakmp_attributes(struct isakmp_attribute *);
extern void free_isakmp_packet(struct isakmp_packet *p);
+extern void flatten_isakmp_payloads(struct isakmp_payload *p, uint8_t ** result, size_t * size);
extern void flatten_isakmp_payload(struct isakmp_payload *p, uint8_t ** result, size_t * size);
extern void flatten_isakmp_packet(struct isakmp_packet *p,
uint8_t ** result, size_t * size, size_t blksz);
Modified: branches/vpnc-nortel/sysdep.c
==============================================================================
--- branches/vpnc-nortel/sysdep.c (original)
+++ branches/vpnc-nortel/sysdep.c Sun Jun 15 16:43:50 2008
@@ -495,6 +495,7 @@
}
close(ip_fd);
+ ip_fd = -1;
close(fd);
return 0;
}
Modified: branches/vpnc-nortel/tunip.c
==============================================================================
--- branches/vpnc-nortel/tunip.c (original)
+++ branches/vpnc-nortel/tunip.c Sun Jun 15 16:43:50 2008
@@ -212,7 +212,7 @@
}
if( r == 1 && *buf == 0xff )
{
- DEBUG(1, "UDP NAT keepalive packet received" );
+ DEBUG(1, printf("UDP NAT keepalive packet received"));
return -1;
}
if (r < s->ipsec.em->fixed_header_size) {
Modified: branches/vpnc-nortel/vpnc.c
==============================================================================
--- branches/vpnc-nortel/vpnc.c (original)
+++ branches/vpnc-nortel/vpnc.c Sun Jun 15 16:43:50 2008
@@ -97,6 +97,10 @@
0x4A, 0x13, 0x1C, 0x81, 0x07, 0x03, 0x58, 0x45,
0x5C, 0x57, 0x28, 0xF2, 0x0E, 0x95, 0x45, 0x2F
};
+const unsigned char VID_CWR[] = { /* DWR support - whatever that is */
+ 0x2D, 0x79, 0x22, 0xC6, 0xB3, 0x01, 0xD9, 0xB0,
+ 0xE1, 0x34, 0x27, 0x39, 0xE9, 0xCF, 0xBB, 0xD5
+};
const unsigned char VID_CISCO_FRAG[] = { /* "FRAGMENTATION" */
0x40, 0x48, 0xB7, 0xD5, 0x6E, 0xBC, 0xE8, 0x85,
0x25, 0xE7, 0xDE, 0x7F, 0x00, 0xD6, 0xC2, 0xD3,
@@ -132,6 +136,7 @@
{ VID_NATT_02, sizeof(VID_NATT_02), "Nat-T 02" },
{ VID_NATT_02N, sizeof(VID_NATT_02N), "Nat-T 02N" },
{ VID_NATT_RFC, sizeof(VID_NATT_RFC), "Nat-T RFC" },
+ { VID_CWR, sizeof(VID_CWR), "CWR??" },
{ VID_CISCO_FRAG, sizeof(VID_CISCO_FRAG), "Cisco Fragmentation" },
{ VID_NETSCREEN_15, sizeof(VID_NETSCREEN_15), "Netscreen 15" },
{ VID_NORTEL_CONT, sizeof(VID_NORTEL_CONT), "Nortel Contivity" },
@@ -234,6 +239,57 @@
s->src = name.sin_addr;
return sock;
+}
+
+static void cleanup(struct sa_block *s) {
+ if (s->ike_fd != 0) {
+ close(s->ike_fd);
+ s->ike_fd = 0;
+ }
+ if (s->esp_fd != 0) {
+ close(s->esp_fd);
+ s->esp_fd = 0;
+ }
+ if (s->ike.resend_hash) {
+ free(s->ike.resend_hash);
+ s->ike.resend_hash = NULL;
+ }
+ if (s->ike.skeyid_d) {
+ free(s->ike.skeyid_d);
+ s->ike.skeyid_d = NULL;
+ }
+ if (s->ike.skeyid_a) {
+ free(s->ike.skeyid_a);
+ s->ike.skeyid_a = NULL;
+ }
+ if (s->ike.initial_iv) {
+ free(s->ike.initial_iv);
+ s->ike.initial_iv = NULL;
+ }
+ if (s->ike.current_iv) {
+ free(s->ike.current_iv);
+ s->ike.current_iv = NULL;
+ }
+ if (s->ike.key) {
+ free(s->ike.key);
+ s->ike.key = NULL;
+ }
+ if (s->ipsec.rx.key) {
+ free(s->ipsec.rx.key);
+ s->ipsec.rx.key = NULL;
+ }
+ if (s->ipsec.tx.key) {
+ free(s->ipsec.tx.key);
+ s->ipsec.tx.key = NULL;
+ }
+ if (s->ipsec.rx.cry_ctx) {
+ gcry_cipher_close(s->ipsec.rx.cry_ctx);
+ s->ipsec.rx.cry_ctx = NULL;
+ }
+ if (s->ipsec.tx.cry_ctx) {
+ gcry_cipher_close(s->ipsec.tx.cry_ctx);
+ s->ipsec.tx.cry_ctx = NULL;
+ }
}
static void init_sockaddr(struct in_addr *dst, const char *hostname)
@@ -522,13 +578,17 @@
{
r = parse_isakmp_packet(r_packet, r_length, &reject);
- if (reject != 0)
+ if (reject != 0) {
+ if (r) free_isakmp_packet(r);
return reject;
+ }
}
/* Verify the basic stuff. */
- if (r->flags != ISAKMP_FLAG_E)
+ if (r->flags != ISAKMP_FLAG_E) {
+ free_isakmp_packet(r);
return ISAKMP_N_INVALID_FLAGS;
+ }
{
size_t sz, spos;
@@ -536,8 +596,10 @@
unsigned char *expected_hash;
struct isakmp_payload *h = r->payload;
- if (h == NULL || h->type != ISAKMP_PAYLOAD_HASH || h->u.hash.length != s->ike.md_len)
+ if (h == NULL || h->type != ISAKMP_PAYLOAD_HASH || h->u.hash.length != s->ike.md_len) {
+ free_isakmp_packet(r);
return ISAKMP_N_INVALID_HASH_INFORMATION;
+ }
spos = (ISAKMP_PAYLOAD_O + (r_packet[ISAKMP_PAYLOAD_O + 2] << 8)
+ r_packet[ISAKMP_PAYLOAD_O + 3]);
@@ -565,8 +627,10 @@
reject = ISAKMP_N_AUTHENTICATION_FAILED;
gcry_md_close(hm);
#if 0
- if (reject != 0)
+ if (reject != 0) {
+ free_isakmp_packet(r);
return reject;
+ }
#endif
}
*r_p = r;
@@ -620,7 +684,7 @@
gcry_md_write(hm, nonce_r, nr_len);
if (pl != NULL) {
- flatten_isakmp_payload(pl, &pl_flat, &pl_size);
+ flatten_isakmp_payloads(pl, &pl_flat, &pl_size);
gcry_md_write(hm, pl_flat, pl_size);
memset(pl_flat, 0, pl_size);
free(pl_flat);
@@ -1015,8 +1079,8 @@
*((uint32_t *) a->u.lots.data) = htonl(2147483);
a = new_isakmp_attribute_16(IKE_ATTRIB_LIFE_TYPE, IKE_LIFE_TYPE_SECONDS, a);
}
+ a = new_isakmp_attribute_16(IKE_ATTRIB_AUTH_METHOD, auth, a);
a = new_isakmp_attribute_16(IKE_ATTRIB_GROUP_DESC, dh_group, a);
- a = new_isakmp_attribute_16(IKE_ATTRIB_AUTH_METHOD, auth, a);
a = new_isakmp_attribute_16(IKE_ATTRIB_HASH, hash, a);
a = new_isakmp_attribute_16(IKE_ATTRIB_ENC, crypt, a);
if (keylen != 0)
@@ -1165,6 +1229,7 @@
unsigned char *psk_hash;
struct isakmp_packet *p1;
+ struct isakmp_packet *r;
int seen_natt_vid = 0, seen_natd = 0, seen_natd_them = 0, seen_natd_us = 0, natd_type = 0;
unsigned char *natd_us = NULL, *natd_them = NULL;
int natt_draft = -1;
@@ -1257,7 +1322,6 @@
DEBUGTOP(2, printf("S4.4 AM_packet2\n"));
/* Decode the recieved packet. */
{
- struct isakmp_packet *r;
int reject;
struct isakmp_payload *rp;
struct isakmp_payload *nonce = NULL;
@@ -1606,6 +1670,7 @@
DEBUG(3, printf("(not dumping psk hash)\n"));
else
hex_dump("psk_skeyid", psk_skeyid, s->ike.md_len, NULL);
+ free(psk_skeyid);
gcry_md_close(skeyid_ctx);
DEBUG(99, printf("shared-key: %s\n",shared_key));
@@ -1660,9 +1725,6 @@
sa = p1->payload;
for (idi = sa; idi->type != ISAKMP_PAYLOAD_ID; idi = idi->next) ;
- sa->next = NULL;
- idi->next = NULL;
- idp->next = NULL;
flatten_isakmp_payload(sa, &sa_f, &sa_size);
flatten_isakmp_payload(idi, &idi_f, &idi_size);
flatten_isakmp_payload(idp, &idp_f, &idp_size);
@@ -1830,8 +1892,8 @@
/* End PRESHARED_KEY_HASH */
free(sa_f);
- free(idi);
- free(idp);
+ free(idi_f);
+ free(idp_f);
}
/* Determine all the SKEYID_x keys. */
@@ -1854,6 +1916,7 @@
gcry_md_write(hm, s->ike.r_cookie, ISAKMP_COOKIE_LENGTH);
gcry_md_write(hm, c012 + 0, 1);
gcry_md_final(hm);
+ if (s->ike.skeyid_d) free(s->ike.skeyid_d);
s->ike.skeyid_d = xallocc(s->ike.md_len);
memcpy(s->ike.skeyid_d, gcry_md_read(hm, 0), s->ike.md_len);
gcry_md_close(hm);
@@ -1867,6 +1930,7 @@
gcry_md_write(hm, s->ike.r_cookie, ISAKMP_COOKIE_LENGTH);
gcry_md_write(hm, c012 + 1, 1);
gcry_md_final(hm);
+ if (s->ike.skeyid_a) free(s->ike.skeyid_a);
s->ike.skeyid_a = xallocc(s->ike.md_len);
memcpy(s->ike.skeyid_a, gcry_md_read(hm, 0), s->ike.md_len);
gcry_md_close(hm);
@@ -1886,8 +1950,10 @@
hex_dump("skeyid_e", skeyid_e, s->ike.md_len, NULL);
memset(dh_shared_secret, 0, sizeof(dh_shared_secret));
+ free(dh_shared_secret);
/* Determine the IKE encryption key. */
+ if (s->ike.key) free(s->ike.key);
s->ike.key = xallocc(s->ike.keylen);
if (s->ike.keylen > s->ike.md_len) {
@@ -1910,6 +1976,7 @@
hex_dump("enc-key", s->ike.key, s->ike.keylen, NULL);
memset(skeyid_e, 0, s->ike.md_len);
+ free(skeyid_e);
}
/* Determine the initial IV. */
@@ -1921,6 +1988,7 @@
gcry_md_write(hm, dh_public, dh_getlen(dh_grp));
gcry_md_write(hm, ke->u.ke.data, ke->u.ke.length);
gcry_md_final(hm);
+ if (s->ike.current_iv) free(s->ike.current_iv);
s->ike.current_iv = xallocc(s->ike.ivlen);
memcpy(s->ike.current_iv, gcry_md_read(hm, 0), s->ike.ivlen);
gcry_md_close(hm);
@@ -2056,6 +2124,7 @@
free_isakmp_packet(p2);
isakmp_crypt(s, p2kt, p2kt_len, 1);
+ if (s->ike.initial_iv) free(s->ike.initial_iv);
s->ike.initial_iv = xallocc(s->ike.ivlen);
memcpy(s->ike.initial_iv, s->ike.current_iv, s->ike.ivlen);
hex_dump("initial_iv", s->ike.initial_iv, s->ike.ivlen, NULL);
@@ -2067,8 +2136,11 @@
DEBUGTOP(2, printf("S4.6 cleanup\n"));
free_isakmp_packet(p1);
+ free_isakmp_packet(r);
free(returned_hash);
free(dh_public);
+ free(dh_shared_secret);
+ free(psk_hash);
group_free(dh_grp);
}
@@ -2145,7 +2217,7 @@
static int do_phase2_xauth(struct sa_block *s)
{
- struct isakmp_packet *r;
+ struct isakmp_packet *r = NULL;
int loopcount;
int reject;
int passwd_used = 0;
@@ -2162,9 +2234,13 @@
DEBUGTOP(2, printf("S5.2 notice_check\n"));
/* recv and check for notices */
+ if (r) free_isakmp_packet(r);
+ r = NULL;
reject = do_phase2_notice_check(s, &r);
- if (reject == -1)
+ if (reject == -1) {
+ if (r) free_isakmp_packet(r);
return 1;
+ }
DEBUGTOP(2, printf("S5.3 type-is-xauth check\n"));
/* Check the transaction type is OK. */
@@ -2374,8 +2450,10 @@
r->message_id, 0, 0, 0, 0, 0, 0, 0);
reject = do_phase2_notice_check(s, &r);
- if (reject == -1)
+ if (reject == -1) {
+ free_isakmp_packet(r);
return 1;
+ }
}
DEBUGTOP(2, printf("S5.6 process xauth response\n"));
@@ -2446,6 +2524,7 @@
a = new_isakmp_attribute(ISAKMP_MODECFG_ATTRIB_CISCO_BANNER, a);
a = new_isakmp_attribute(ISAKMP_MODECFG_ATTRIB_CISCO_DO_PFS, a);
+ /* a = new_isakmp_attribute(ISAKMP_MODECFG_ATTRIB_CISCO_FW_TYPE, a); */
if (opt_natt_mode == NATT_CISCO_UDP)
a = new_isakmp_attribute(ISAKMP_MODECFG_ATTRIB_CISCO_UDP_ENCAP_PORT, a);
a = new_isakmp_attribute(ISAKMP_MODECFG_ATTRIB_CISCO_DEF_DOMAIN, a);
@@ -2463,8 +2542,10 @@
/* recv and check for notices */
reject = do_phase2_notice_check(s, &r);
- if (reject == -1)
+ if (reject == -1) {
+ if (r) free_isakmp_packet(r);
return 1;
+ }
if (opt_vendor != VENDOR_NORTEL) {
/* Check the transaction type & message ID are OK. */
@@ -2533,6 +2614,7 @@
r->message_id, 1, 0, 0, 0, 0, 0, 0);
}
+ free_isakmp_packet(r);
return 0;
}
@@ -2901,7 +2983,7 @@
DEBUGTOP(2, printf("do_phase2: S7.1 QM_packet1\n"));
gcry_create_nonce((uint8_t *) & s->ipsec.rx.spi, sizeof(s->ipsec.rx.spi));
- rp = make_our_sa_ipsec_nortel(s, transform, proposal->u.p.number);
+ rp = make_our_sa_ipsec_nortel(s, transform, proposal->u.p.number); /* FIXME: LEAK: allocated memory never freed */
gcry_create_nonce((uint8_t *) nonce, sizeof(nonce));
rp->next = new_isakmp_data_payload(ISAKMP_PAYLOAD_NONCE, nonce, sizeof(nonce));
@@ -2984,7 +3066,7 @@
}
gcry_create_nonce((uint8_t *) & s->ipsec.rx.spi, sizeof(s->ipsec.rx.spi));
- rp = make_our_sa_ipsec(s);
+ rp = make_our_sa_ipsec(s); /* FIXME: LEAK: allocated memory never freed */
gcry_create_nonce((uint8_t *) nonce_i, sizeof(nonce_i));
rp->next = new_isakmp_data_payload(ISAKMP_PAYLOAD_NONCE, nonce_i, sizeof(nonce_i));
@@ -3027,6 +3109,8 @@
DEBUGTOP(2, printf("S7.3 QM_packet2 validate type\n"));
reject = unpack_verify_phase2(s, r_packet, r_length, &r, nonce_i, sizeof(nonce_i));
+
+ /* FIXME: LEAK: r not freed */
if (((reject == 0) || (reject == ISAKMP_N_AUTHENTICATION_FAILED))
&& r->exchange_type == ISAKMP_EXCHANGE_INFORMATIONAL) {
@@ -3273,6 +3357,8 @@
if (dh_grp)
group_free(dh_grp);
+ if (dh_shared_secret)
+ free(dh_shared_secret);
}
if ((opt_natt_mode == NATT_CISCO_UDP) && s->ipsec.peer_udpencap_port) {
@@ -3343,6 +3429,7 @@
del_msgid, 1, NULL, NULL,
NULL, 0, NULL, 0);
}
+ if (dh_public) free(dh_public);
}
static int do_rekey(struct sa_block *s, struct isakmp_packet *r)
@@ -3550,22 +3637,29 @@
reject = unpack_verify_phase2(s, r_packet, r_length, &r, NULL, 0);
/* just ignore broken stuff for now */
- if (reject != 0)
+ if (reject != 0) {
+ if (r) free_isakmp_packet(r);
return;
+ }
/* everything must be encrypted by now */
- if (r->payload == NULL || r->payload->type != ISAKMP_PAYLOAD_HASH)
+ if (r->payload == NULL || r->payload->type != ISAKMP_PAYLOAD_HASH) {
+ free_isakmp_packet(r);
return;
+ }
/* empty packet? well, nothing to see here */
- if (r->payload->next == NULL)
+ if (r->payload->next == NULL) {
+ free_isakmp_packet(r);
return;
+ }
/* do we get an SA proposal for rekeying? */
if (r->exchange_type == ISAKMP_EXCHANGE_IKE_QUICK &&
r->payload->next->type == ISAKMP_PAYLOAD_SA) {
reject = do_rekey(s, r);
DEBUG(3, printf("do_rekey returned: %d\n", reject));
+ free_isakmp_packet(r);
return;
}
@@ -3628,9 +3722,11 @@
*/
do_kill = -1;
DEBUG(2, printf("got isakmp-delete, terminating...\n"));
+ free_isakmp_packet(r);
return;
}
+ free_isakmp_packet(r);
return;
}
@@ -3694,6 +3790,8 @@
setup_link(s);
DEBUGTOP(2, printf("S8 close_tunnel\n"));
close_tunnel();
+ DEBUGTOP(2, printf("S9 cleanup\n"));
+ cleanup(s);
return 0;
}
More information about the vpnc-devel
mailing list