From 0e592faadecfb3bc2705bf0d9e434163e4b914ca Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Fri, 16 Jan 2009 18:10:21 +0000 Subject: fixed packet length errors --- src/auth_algo.c | 2 +- src/bsd/tun.c | 3 +++ src/encrypted_packet.c | 5 +++++ src/encrypted_packet.h | 2 ++ src/linux/tun.c | 3 +++ src/plain_packet.c | 5 +++++ src/plain_packet.h | 2 ++ src/uanytun.c | 14 +++++++++++--- 8 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/auth_algo.c b/src/auth_algo.c index f8fc34d..0a45aff 100644 --- a/src/auth_algo.c +++ b/src/auth_algo.c @@ -226,7 +226,7 @@ void auth_algo_sha1_generate(auth_algo_t* aa, key_derivation_t* kd, key_store_di int auth_algo_sha1_check_tag(auth_algo_t* aa, key_derivation_t* kd, key_store_dir_t dir, encrypted_packet_t* packet) { if(!encrypted_packet_get_auth_tag_length(packet)) - return 1; + return 0; if(!aa || !aa->params_) { log_printf(ERR, "auth algo not initialized"); diff --git a/src/bsd/tun.c b/src/bsd/tun.c index b609a3c..43da1d0 100644 --- a/src/bsd/tun.c +++ b/src/bsd/tun.c @@ -256,6 +256,9 @@ int tun_write(tun_device_t* dev, u_int8_t* buf, u_int32_t len) if(!dev || dev->fd_ < 0) return -1; + if(!buf) + return 0; + if(dev->with_pi_) { struct iovec iov[2]; diff --git a/src/encrypted_packet.c b/src/encrypted_packet.c index eb21828..2cc4e5f 100644 --- a/src/encrypted_packet.c +++ b/src/encrypted_packet.c @@ -47,6 +47,11 @@ void encrypted_packet_init(encrypted_packet_t* packet) memset (packet, 0, sizeof(*packet)); } +u_int32_t encrypted_packet_get_header_length() +{ + return sizeof(encrypted_packet_header_t); +} + u_int8_t* encrypted_packet_get_packet(encrypted_packet_t* packet) { if(!packet) diff --git a/src/encrypted_packet.h b/src/encrypted_packet.h index e35ca25..9061f3d 100644 --- a/src/encrypted_packet.h +++ b/src/encrypted_packet.h @@ -62,6 +62,8 @@ typedef struct encrypted_packet_struct encrypted_packet_t; void encrypted_packet_init(encrypted_packet_t* packet); +u_int32_t encrypted_packet_get_header_length(); + u_int8_t* encrypted_packet_get_packet(encrypted_packet_t* packet); u_int32_t encrypted_packet_get_length(encrypted_packet_t* packet); void encrypted_packet_set_length(encrypted_packet_t* packet, u_int32_t len); diff --git a/src/linux/tun.c b/src/linux/tun.c index bcf1885..88d6d6e 100644 --- a/src/linux/tun.c +++ b/src/linux/tun.c @@ -157,6 +157,9 @@ int tun_write(tun_device_t* dev, u_int8_t* buf, u_int32_t len) if(!dev || dev->fd_ < 0) return -1; + if(!buf) + return 0; + if(dev->with_pi_) { struct iovec iov[2]; diff --git a/src/plain_packet.c b/src/plain_packet.c index 8b63e4a..5675c63 100644 --- a/src/plain_packet.c +++ b/src/plain_packet.c @@ -50,6 +50,11 @@ void plain_packet_init(plain_packet_t* packet) memset (packet, 0, sizeof(*packet)); } +u_int32_t plain_packet_get_header_length() +{ + return sizeof(payload_type_t); +} + u_int8_t* plain_packet_get_packet(plain_packet_t* packet) { if(!packet) diff --git a/src/plain_packet.h b/src/plain_packet.h index 723fe5a..c35e1ef 100644 --- a/src/plain_packet.h +++ b/src/plain_packet.h @@ -54,6 +54,8 @@ typedef struct plain_packet_struct plain_packet_t; void plain_packet_init(plain_packet_t* packet); +u_int32_t plain_packet_get_header_length(); + u_int8_t* plain_packet_get_packet(plain_packet_t* packet); u_int32_t plain_packet_get_length(plain_packet_t* packet); void plain_packet_set_length(plain_packet_t* packet, u_int32_t len); diff --git a/src/uanytun.c b/src/uanytun.c index 27f208f..1acf2a1 100644 --- a/src/uanytun.c +++ b/src/uanytun.c @@ -182,9 +182,12 @@ int process_sock_data(tun_device_t* dev, udp_socket_t* sock, options_t* opt, pla log_printf(ERR, "error on receiving udp packet: %m"); return 0; } - + else if(len < encrypted_packet_get_header_length()) { + log_printf(WARNING, "received packet is to short"); + return 0; + } encrypted_packet_set_length(encrypted_packet, len); - + #ifndef NO_CRYPT if(!auth_algo_check_tag(aa, kd, kd_inbound, encrypted_packet)) { log_printf(WARNING, "wrong authentication tag, discarding packet"); @@ -213,7 +216,12 @@ int process_sock_data(tun_device_t* dev, udp_socket_t* sock, options_t* opt, pla log_printf(NOTICE, "autodetected remote host changed %s", addrstring); free(addrstring); } - + + if(encrypted_packet_get_payload_length(encrypted_packet) <= plain_packet_get_header_length()) { + log_printf(WARNING, "ignoring packet with zero length payload"); + return 0; + } + int ret = cipher_decrypt(c, kd, kd_inbound, encrypted_packet, plain_packet); if(ret) return ret; -- cgit v1.2.3