diff options
author | paul <paul> | 2006-01-17 17:26:25 +0000 |
---|---|---|
committer | paul <paul> | 2006-01-17 17:26:25 +0000 |
commit | 98fd1e61212ea98154e7cc4b6deed41a07794523 (patch) | |
tree | 961f28ead9a2eb24fb7660cd52023489a7b431e2 /ripd | |
parent | 6726f950ad25daa532e75dc7a6875b340ae0447d (diff) |
[ripd] Fix verification of received MD5 authenticated packets
2006-01-17 Paul Jakma <paul.jakma@sun.com>
* ripd.c: (rip_auth_md5) remove pdigest, not needed.
Use a local buffer for the auth_str, where it can be properly
nul padded. Do so, hence fixing MD5 authentication.
Key looked up via key ring should be used in preference to
the RIPv1 simple password, not other way around.
No need to copy around digests, we can reference them
directly.
The auth_len received can't be trusted, some implementations
lie (e.g. older ripd).
(rip_auth_md5_ah_write) rename len local variable to doff
to be consistent with other functions.
(rip_auth_header_write) add the missing return.
(rip_auth_md5_set) use the proper constructs to access stream.
Diffstat (limited to 'ripd')
-rw-r--r-- | ripd/ChangeLog | 16 | ||||
-rw-r--r-- | ripd/ripd.c | 40 |
2 files changed, 33 insertions, 23 deletions
diff --git a/ripd/ChangeLog b/ripd/ChangeLog index a3c0e24b..2b79a61d 100644 --- a/ripd/ChangeLog +++ b/ripd/ChangeLog @@ -1,3 +1,19 @@ +2006-01-17 Paul Jakma <paul.jakma@sun.com> + + * ripd.c: (rip_auth_md5) remove pdigest, not needed. + Use a local buffer for the auth_str, where it can be properly + nul padded. Do so, hence fixing MD5 authentication. + Key looked up via key ring should be used in preference to + the RIPv1 simple password, not other way around. + No need to copy around digests, we can reference them + directly. + The auth_len received can't be trusted, some implementations + lie (e.g. older ripd). + (rip_auth_md5_ah_write) rename len local variable to doff + to be consistent with other functions. + (rip_auth_header_write) add the missing return. + (rip_auth_md5_set) use the proper constructs to access stream. + 2005-10-30 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * ripd.c: (rip_response_process) Instead of calling diff --git a/ripd/ripd.c b/ripd/ripd.c index ec7bd199..40db33f5 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -865,10 +865,9 @@ rip_auth_md5 (struct rip_packet *packet, struct sockaddr_in *from, struct keychain *keychain; struct key *key; MD5_CTX ctx; - u_char pdigest[RIP_AUTH_MD5_SIZE]; u_char digest[RIP_AUTH_MD5_SIZE]; u_int16_t packet_len; - char *auth_str = NULL; + char auth_str[RIP_AUTH_MD5_SIZE]; if (IS_RIP_DEBUG_EVENT) zlog_debug ("RIPv2 MD5 authentication from %s", @@ -884,7 +883,7 @@ rip_auth_md5 (struct rip_packet *packet, struct sockaddr_in *from, /* If the authentication length is less than 16, then it must be wrong for * any interpretation of rfc2082. Some implementations also interpret * this as RIP_HEADER_SIZE+ RIP_AUTH_MD5_SIZE, aka RIP_AUTH_MD5_COMPAT_SIZE. - */ + */ if ( !((md5->auth_len == RIP_AUTH_MD5_SIZE) || (md5->auth_len == RIP_AUTH_MD5_COMPAT_SIZE))) { @@ -908,6 +907,8 @@ rip_auth_md5 (struct rip_packet *packet, struct sockaddr_in *from, /* retrieve authentication data */ md5data = (struct rip_md5_data *) (((u_char *) packet) + packet_len); + + memset (auth_str, 0, RIP_AUTH_MD5_SIZE); if (ri->key_chain) { @@ -919,30 +920,22 @@ rip_auth_md5 (struct rip_packet *packet, struct sockaddr_in *from, if (key == NULL) return 0; - auth_str = key->string; + strncpy (auth_str, key->string, RIP_AUTH_MD5_SIZE); } - - if (ri->auth_str) - auth_str = ri->auth_str; + else if (ri->auth_str) + strncpy (auth_str, ri->auth_str, RIP_AUTH_MD5_SIZE); if (! auth_str) return 0; - + /* MD5 digest authentication. */ - - /* Save digest to pdigest. */ - memcpy (pdigest, md5data->digest, RIP_AUTH_MD5_SIZE); - - /* Overwrite digest by my secret. */ - memset (md5data->digest, 0, RIP_AUTH_MD5_SIZE); - strncpy ((char *)md5data->digest, auth_str, RIP_AUTH_MD5_SIZE); - memset (&ctx, 0, sizeof(ctx)); MD5Init(&ctx); - MD5Update(&ctx, packet, packet_len + md5->auth_len); + MD5Update(&ctx, packet, packet_len + RIP_HEADER_SIZE); + MD5Update(&ctx, auth_str, RIP_AUTH_MD5_SIZE); MD5Final(digest, &ctx); - - if (memcmp (pdigest, digest, RIP_AUTH_MD5_SIZE) == 0) + + if (memcmp (md5data->digest, digest, RIP_AUTH_MD5_SIZE) == 0) return packet_len; else return 0; @@ -1000,7 +993,7 @@ static size_t rip_auth_md5_ah_write (struct stream *s, struct rip_interface *ri, struct key *key) { - size_t len = 0; + size_t doff = 0; assert (s && ri && ri->auth_type == RIP_AUTH_MD5); @@ -1013,7 +1006,7 @@ rip_auth_md5_ah_write (struct stream *s, struct rip_interface *ri, * Set to placeholder value here, to true value when RIP-2 Packet length * is known. Actual value is set in .....(). */ - len = stream_get_endp(s); + doff = stream_get_endp(s); stream_putw (s, 0); /* Key ID. */ @@ -1038,7 +1031,7 @@ rip_auth_md5_ah_write (struct stream *s, struct rip_interface *ri, stream_putl (s, 0); stream_putl (s, 0); - return len; + return doff; } /* If authentication is in used, write the appropriate header @@ -1061,6 +1054,7 @@ rip_auth_header_write (struct stream *s, struct rip_interface *ri, return rip_auth_md5_ah_write (s, ri, key); } assert (1); + return 0; } /* Write RIPv2 MD5 authentication data trailer */ @@ -1097,7 +1091,7 @@ rip_auth_md5_set (struct stream *s, struct rip_interface *ri, size_t doff, /* Generate a digest for the RIP packet. */ memset(&ctx, 0, sizeof(ctx)); MD5Init(&ctx); - MD5Update(&ctx, s->data, s->endp); + MD5Update(&ctx, STREAM_DATA (s), stream_get_endp (s)); MD5Update(&ctx, auth_str, RIP_AUTH_MD5_SIZE); MD5Final(digest, &ctx); |