diff options
-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); |