mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-05-03 23:15:59 +00:00
2005-02-04 Paul Jakma <paul@dishone.st>
* ripd.c: Untangle the construction of RIP auth data. (rip_auth_prepare_str_send) new helper function, prepare correct key string. (rip_auth_simple_write) new helper, write out the rip simple password auth psuedo-RTE. (rip_auth_md5_ah_write) new helper, write out the MD5 auth-header psuedo-RTE. (rip_auth_header_write) new helper, write out correct auth header data / psuedo-RTE. (rip_auth_md5_set) rip out the memmove and writing of the auth header psuedo-RTE. So that all that is left is to write the trailing auth digest, and update digest offset field in the original header. (rip_write_rte) rip out writing of RIP header, writing of simple auth data psuedo-RTE. Make it do what its name suggests, write out actual RTEs. (rip_output_process) remove the incorrect additional decrements of rtemax. Prepare the auth_str, which simple or MD5 auth will need. Move write out of RIP header and auth data to inside the loop. Adjust paramaters as required.
This commit is contained in:
parent
c4c7d0c48b
commit
b14ee00b7f
@ -1,3 +1,26 @@
|
|||||||
|
2005-02-04 Paul Jakma <paul@dishone.st>
|
||||||
|
|
||||||
|
* ripd.c: Untangle the construction of RIP auth data.
|
||||||
|
(rip_auth_prepare_str_send) new helper function, prepare
|
||||||
|
correct key string.
|
||||||
|
(rip_auth_simple_write) new helper, write out the
|
||||||
|
rip simple password auth psuedo-RTE.
|
||||||
|
(rip_auth_md5_ah_write) new helper, write out the
|
||||||
|
MD5 auth-header psuedo-RTE.
|
||||||
|
(rip_auth_header_write) new helper, write out correct
|
||||||
|
auth header data / psuedo-RTE.
|
||||||
|
(rip_auth_md5_set) rip out the memmove and writing of the
|
||||||
|
auth header psuedo-RTE. So that all that is left is to
|
||||||
|
write the trailing auth digest, and update digest offset
|
||||||
|
field in the original header.
|
||||||
|
(rip_write_rte) rip out writing of RIP header, writing of
|
||||||
|
simple auth data psuedo-RTE. Make it do what its name suggests,
|
||||||
|
write out actual RTEs.
|
||||||
|
(rip_output_process) remove the incorrect additional decrements
|
||||||
|
of rtemax. Prepare the auth_str, which simple or MD5 auth will
|
||||||
|
need. Move write out of RIP header and auth data to inside the
|
||||||
|
loop. Adjust paramaters as required.
|
||||||
|
|
||||||
2005-01-30 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
|
2005-01-30 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
|
||||||
|
|
||||||
* ripd.c: (rip_create_socket) Replace perror with zlog_err.
|
* ripd.c: (rip_create_socket) Replace perror with zlog_err.
|
||||||
|
259
ripd/ripd.c
259
ripd/ripd.c
@ -929,72 +929,73 @@ rip_auth_md5 (struct rip_packet *packet, struct sockaddr_in *from,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
/* Pick correct auth string for sends, prepare auth_str buffer for use.
|
||||||
rip_auth_md5_set (struct stream *s, struct interface *ifp)
|
* (left justified and padded).
|
||||||
|
*
|
||||||
|
* presumes one of ri or key is valid, and that the auth strings they point
|
||||||
|
* to are nul terminated. If neither are present, auth_str will be fully
|
||||||
|
* zero padded.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
rip_auth_prepare_str_send (struct rip_interface *ri, struct key *key,
|
||||||
|
char *auth_str, int len)
|
||||||
{
|
{
|
||||||
struct rip_interface *ri;
|
assert (ri || key);
|
||||||
struct keychain *keychain = NULL;
|
|
||||||
struct key *key = NULL;
|
|
||||||
unsigned long len;
|
|
||||||
struct md5_ctx ctx;
|
|
||||||
unsigned char secret[RIP_AUTH_MD5_SIZE];
|
|
||||||
unsigned char digest[RIP_AUTH_MD5_SIZE];
|
|
||||||
char *auth_str = NULL;
|
|
||||||
|
|
||||||
ri = ifp->info;
|
memset (auth_str, 0, len);
|
||||||
|
if (key && key->string)
|
||||||
|
strncpy (auth_str, key->string, len);
|
||||||
|
else if (ri->auth_str)
|
||||||
|
strncpy (auth_str, ri->auth_str, len);
|
||||||
|
|
||||||
/* Make it sure this interface is configured as MD5
|
|
||||||
authentication. */
|
|
||||||
if (ri->auth_type != RIP_AUTH_MD5)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Lookup key chain. */
|
|
||||||
if (ri->key_chain)
|
|
||||||
{
|
|
||||||
keychain = keychain_lookup (ri->key_chain);
|
|
||||||
if (keychain == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Lookup key. */
|
|
||||||
key = key_lookup_for_send (keychain);
|
|
||||||
if (key == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
auth_str = key->string;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ri->auth_str)
|
|
||||||
auth_str = ri->auth_str;
|
|
||||||
|
|
||||||
if (! auth_str)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Get packet length. */
|
|
||||||
len = s->putp;
|
|
||||||
|
|
||||||
/* Check packet length. */
|
|
||||||
if (len < (RIP_HEADER_SIZE + RIP_RTE_SIZE))
|
|
||||||
{
|
|
||||||
zlog_err ("rip_auth_md5_set(): packet length %ld is less than minimum length.", len);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Move RTE. */
|
/* Write RIPv2 simple password authentication information
|
||||||
memmove (s->data + RIP_HEADER_SIZE + RIP_RTE_SIZE,
|
*
|
||||||
s->data + RIP_HEADER_SIZE,
|
* auth_str is presumed to be 2 bytes and correctly prepared
|
||||||
len - RIP_HEADER_SIZE);
|
* (left justified and zero padded).
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
rip_auth_simple_write (struct stream *s, char *auth_str, int len)
|
||||||
|
{
|
||||||
|
assert (s && len == RIP_AUTH_SIMPLE_SIZE);
|
||||||
|
|
||||||
/* Set pointer to authentication header. */
|
stream_putw (s, RIP_FAMILY_AUTH);
|
||||||
stream_set_putp (s, RIP_HEADER_SIZE);
|
stream_putw (s, RIP_AUTH_SIMPLE_PASSWORD);
|
||||||
len += RIP_RTE_SIZE;
|
stream_put (s, auth_str, RIP_AUTH_SIMPLE_SIZE);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* write RIPv2 MD5 "authentication header"
|
||||||
|
* (uses the auth key data field)
|
||||||
|
*
|
||||||
|
* Digest offset field is set to 0.
|
||||||
|
*
|
||||||
|
* returns: offset of the digest offset field, which must be set when
|
||||||
|
* length to the auth-data MD5 digest is known.
|
||||||
|
*/
|
||||||
|
static size_t
|
||||||
|
rip_auth_md5_ah_write (struct stream *s, struct rip_interface *ri,
|
||||||
|
struct key *key)
|
||||||
|
{
|
||||||
|
size_t len = 0;
|
||||||
|
|
||||||
|
assert (s && ri && ri->auth_type == RIP_AUTH_MD5);
|
||||||
|
|
||||||
/* MD5 authentication. */
|
/* MD5 authentication. */
|
||||||
stream_putw (s, RIP_FAMILY_AUTH);
|
stream_putw (s, RIP_FAMILY_AUTH);
|
||||||
stream_putw (s, RIP_AUTH_MD5);
|
stream_putw (s, RIP_AUTH_MD5);
|
||||||
|
|
||||||
/* RIP-2 Packet length. Actual value is filled in
|
/* MD5 AH digest offset field.
|
||||||
rip_auth_md5_set(). */
|
*
|
||||||
stream_putw (s, len);
|
* Set to placeholder value here, to true value when RIP-2 Packet length
|
||||||
|
* is known. Actual value is set in .....().
|
||||||
|
*/
|
||||||
|
len = stream_get_putp(s);
|
||||||
|
stream_putw (s, 0);
|
||||||
|
|
||||||
/* Key ID. */
|
/* Key ID. */
|
||||||
if (key)
|
if (key)
|
||||||
@ -1018,19 +1019,66 @@ rip_auth_md5_set (struct stream *s, struct interface *ifp)
|
|||||||
stream_putl (s, 0);
|
stream_putl (s, 0);
|
||||||
stream_putl (s, 0);
|
stream_putl (s, 0);
|
||||||
|
|
||||||
/* Set pointer to authentication data. */
|
return len;
|
||||||
stream_set_putp (s, len);
|
}
|
||||||
|
|
||||||
|
/* If authentication is in used, write the appropriate header
|
||||||
|
* returns stream offset to which length must later be written
|
||||||
|
* or 0 if this is not required
|
||||||
|
*/
|
||||||
|
static size_t
|
||||||
|
rip_auth_header_write (struct stream *s, struct rip_interface *ri,
|
||||||
|
struct key *key, char *auth_str, int len)
|
||||||
|
{
|
||||||
|
assert (ri->auth_type != RIP_NO_AUTH);
|
||||||
|
|
||||||
|
switch (ri->auth_type)
|
||||||
|
{
|
||||||
|
case RIP_AUTH_SIMPLE_PASSWORD:
|
||||||
|
rip_auth_prepare_str_send (ri, key, auth_str, len);
|
||||||
|
rip_auth_simple_write (s, auth_str, len);
|
||||||
|
return 0;
|
||||||
|
case RIP_AUTH_MD5:
|
||||||
|
return rip_auth_md5_ah_write (s, ri, key);
|
||||||
|
}
|
||||||
|
assert (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write RIPv2 MD5 authentication data trailer */
|
||||||
|
static void
|
||||||
|
rip_auth_md5_set (struct stream *s, struct rip_interface *ri, size_t doff,
|
||||||
|
char *auth_str, int authlen)
|
||||||
|
{
|
||||||
|
unsigned long len;
|
||||||
|
struct md5_ctx ctx;
|
||||||
|
unsigned char digest[RIP_AUTH_MD5_SIZE];
|
||||||
|
|
||||||
|
/* Make it sure this interface is configured as MD5
|
||||||
|
authentication. */
|
||||||
|
assert ((ri->auth_type == RIP_AUTH_MD5) && (authlen == RIP_AUTH_MD5_SIZE));
|
||||||
|
assert (doff > 0);
|
||||||
|
|
||||||
|
/* Get packet length. */
|
||||||
|
len = stream_get_endp(s);
|
||||||
|
|
||||||
|
/* Check packet length. */
|
||||||
|
if (len < (RIP_HEADER_SIZE + RIP_RTE_SIZE))
|
||||||
|
{
|
||||||
|
zlog_err ("rip_auth_md5_set(): packet length %ld is less than minimum length.", len);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the digest offset length in the header */
|
||||||
|
stream_putw_at (s, doff, len);
|
||||||
|
|
||||||
/* Set authentication data. */
|
/* Set authentication data. */
|
||||||
stream_putw (s, RIP_FAMILY_AUTH);
|
stream_putw (s, RIP_FAMILY_AUTH);
|
||||||
stream_putw (s, RIP_AUTH_DATA);
|
stream_putw (s, RIP_AUTH_DATA);
|
||||||
|
|
||||||
/* Generate a digest for the RIP packet. */
|
/* Generate a digest for the RIP packet. */
|
||||||
memset (secret, 0, RIP_AUTH_MD5_SIZE);
|
|
||||||
strncpy ((char *)secret, auth_str, RIP_AUTH_MD5_SIZE);
|
|
||||||
md5_init_ctx (&ctx);
|
md5_init_ctx (&ctx);
|
||||||
md5_process_bytes (s->data, s->endp, &ctx);
|
md5_process_bytes (s->data, s->endp, &ctx);
|
||||||
md5_process_bytes (secret, RIP_AUTH_MD5_SIZE, &ctx);
|
md5_process_bytes (auth_str, RIP_AUTH_MD5_SIZE, &ctx);
|
||||||
md5_finish_ctx (&ctx, digest);
|
md5_finish_ctx (&ctx, digest);
|
||||||
|
|
||||||
/* Copy the digest to the packet. */
|
/* Copy the digest to the packet. */
|
||||||
@ -2015,68 +2063,14 @@ rip_create_socket ()
|
|||||||
return sock;
|
return sock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Write routing table entry to the stream and return next index of
|
/* Write routing table entry to the stream and return next index of
|
||||||
the routing table entry in the stream. */
|
the routing table entry in the stream. */
|
||||||
int
|
int
|
||||||
rip_write_rte (int num, struct stream *s, struct prefix_ipv4 *p,
|
rip_write_rte (int num, struct stream *s, struct prefix_ipv4 *p,
|
||||||
u_char version, struct rip_info *rinfo, struct interface *ifp)
|
u_char version, struct rip_info *rinfo)
|
||||||
{
|
{
|
||||||
struct in_addr mask;
|
struct in_addr mask;
|
||||||
struct rip_interface *ri;
|
|
||||||
|
|
||||||
/* RIP packet header. */
|
|
||||||
if (num == 0)
|
|
||||||
{
|
|
||||||
stream_putc (s, RIP_RESPONSE);
|
|
||||||
stream_putc (s, version);
|
|
||||||
stream_putw (s, 0);
|
|
||||||
|
|
||||||
/* In case of we need RIPv2 authentication. */
|
|
||||||
if (version == RIPv2 && ifp)
|
|
||||||
{
|
|
||||||
ri = ifp->info;
|
|
||||||
|
|
||||||
if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
|
|
||||||
{
|
|
||||||
if (ri->auth_str)
|
|
||||||
{
|
|
||||||
stream_putw (s, RIP_FAMILY_AUTH);
|
|
||||||
stream_putw (s, RIP_AUTH_SIMPLE_PASSWORD);
|
|
||||||
|
|
||||||
memset ((s->data + s->putp), 0, 16);
|
|
||||||
strncpy ((char *)(s->data + s->putp), ri->auth_str, 16);
|
|
||||||
stream_set_putp (s, s->putp + 16);
|
|
||||||
|
|
||||||
num++;
|
|
||||||
}
|
|
||||||
if (ri->key_chain)
|
|
||||||
{
|
|
||||||
struct keychain *keychain;
|
|
||||||
struct key *key;
|
|
||||||
|
|
||||||
keychain = keychain_lookup (ri->key_chain);
|
|
||||||
|
|
||||||
if (keychain)
|
|
||||||
{
|
|
||||||
key = key_lookup_for_send (keychain);
|
|
||||||
|
|
||||||
if (key)
|
|
||||||
{
|
|
||||||
stream_putw (s, RIP_FAMILY_AUTH);
|
|
||||||
stream_putw (s, RIP_AUTH_SIMPLE_PASSWORD);
|
|
||||||
|
|
||||||
memset ((s->data + s->putp), 0, 16);
|
|
||||||
strncpy ((char *)(s->data + s->putp),
|
|
||||||
key->string, 16);
|
|
||||||
stream_set_putp (s, s->putp + 16);
|
|
||||||
|
|
||||||
num++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write routing table entry. */
|
/* Write routing table entry. */
|
||||||
if (version == RIPv1)
|
if (version == RIPv1)
|
||||||
@ -2116,6 +2110,11 @@ rip_output_process (struct connected *ifc, struct sockaddr_in *to,
|
|||||||
struct prefix_ipv4 *p;
|
struct prefix_ipv4 *p;
|
||||||
struct prefix_ipv4 classfull;
|
struct prefix_ipv4 classfull;
|
||||||
struct prefix_ipv4 ifaddrclass;
|
struct prefix_ipv4 ifaddrclass;
|
||||||
|
struct key *key = NULL;
|
||||||
|
/* this might need to made dynamic if RIP ever supported auth methods
|
||||||
|
with larger key string sizes */
|
||||||
|
char auth_str[RIP_AUTH_SIMPLE_SIZE];
|
||||||
|
size_t doff; /* offset of digest offset field */
|
||||||
int num;
|
int num;
|
||||||
int rtemax;
|
int rtemax;
|
||||||
int subnetted = 0;
|
int subnetted = 0;
|
||||||
@ -2153,7 +2152,7 @@ rip_output_process (struct connected *ifc, struct sockaddr_in *to,
|
|||||||
|
|
||||||
/* If output interface is in simple password authentication mode
|
/* If output interface is in simple password authentication mode
|
||||||
and string or keychain is specified we need space for auth. data */
|
and string or keychain is specified we need space for auth. data */
|
||||||
if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
|
if (ri->auth_type != RIP_NO_AUTH)
|
||||||
{
|
{
|
||||||
if (ri->key_chain)
|
if (ri->key_chain)
|
||||||
{
|
{
|
||||||
@ -2161,12 +2160,10 @@ rip_output_process (struct connected *ifc, struct sockaddr_in *to,
|
|||||||
|
|
||||||
keychain = keychain_lookup (ri->key_chain);
|
keychain = keychain_lookup (ri->key_chain);
|
||||||
if (keychain)
|
if (keychain)
|
||||||
if (key_lookup_for_send (keychain))
|
key = key_lookup_for_send (keychain);
|
||||||
rtemax -=1;
|
|
||||||
}
|
}
|
||||||
else
|
/* to be passed to auth functions later */
|
||||||
if (ri->auth_str)
|
rip_auth_prepare_str_send (ri, key, auth_str, RIP_AUTH_SIMPLE_SIZE);
|
||||||
rtemax -=1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (version == RIPv1)
|
if (version == RIPv1)
|
||||||
@ -2345,12 +2342,26 @@ rip_output_process (struct connected *ifc, struct sockaddr_in *to,
|
|||||||
rinfo->metric_out = RIP_METRIC_INFINITY;
|
rinfo->metric_out = RIP_METRIC_INFINITY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Prepare preamble, auth headers, if needs be */
|
||||||
|
if (num == 0)
|
||||||
|
{
|
||||||
|
stream_putc (s, RIP_RESPONSE);
|
||||||
|
stream_putc (s, version);
|
||||||
|
stream_putw (s, 0);
|
||||||
|
|
||||||
|
/* auth header for simple or v2 && MD5 */
|
||||||
|
if ( (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
|
||||||
|
|| (version == RIPv2 && ri->auth_type == RIP_AUTH_MD5) )
|
||||||
|
doff = rip_auth_header_write (s, ri, key, auth_str,
|
||||||
|
RIP_AUTH_SIMPLE_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
/* Write RTE to the stream. */
|
/* Write RTE to the stream. */
|
||||||
num = rip_write_rte (num, s, p, version, rinfo, to ? NULL : ifc->ifp);
|
num = rip_write_rte (num, s, p, version, rinfo);
|
||||||
if (num == rtemax)
|
if (num == rtemax)
|
||||||
{
|
{
|
||||||
if (version == RIPv2 && ri->auth_type == RIP_AUTH_MD5)
|
if (version == RIPv2 && ri->auth_type == RIP_AUTH_MD5)
|
||||||
rip_auth_md5_set (s, ifc->ifp);
|
rip_auth_md5_set (s, ri, doff, auth_str, RIP_AUTH_SIMPLE_SIZE);
|
||||||
|
|
||||||
ret = rip_send_packet (STREAM_DATA (s), stream_get_endp (s),
|
ret = rip_send_packet (STREAM_DATA (s), stream_get_endp (s),
|
||||||
to, ifc);
|
to, ifc);
|
||||||
@ -2367,7 +2378,7 @@ rip_output_process (struct connected *ifc, struct sockaddr_in *to,
|
|||||||
if (num != 0)
|
if (num != 0)
|
||||||
{
|
{
|
||||||
if (version == RIPv2 && ri->auth_type == RIP_AUTH_MD5)
|
if (version == RIPv2 && ri->auth_type == RIP_AUTH_MD5)
|
||||||
rip_auth_md5_set (s, ifc->ifp);
|
rip_auth_md5_set (s, ri, doff, auth_str, RIP_AUTH_SIMPLE_SIZE);
|
||||||
|
|
||||||
ret = rip_send_packet (STREAM_DATA (s), stream_get_endp (s), to, ifc);
|
ret = rip_send_packet (STREAM_DATA (s), stream_get_endp (s), to, ifc);
|
||||||
|
|
||||||
|
@ -87,6 +87,9 @@
|
|||||||
#define RIP_AUTH_SIMPLE_PASSWORD 2
|
#define RIP_AUTH_SIMPLE_PASSWORD 2
|
||||||
#define RIP_AUTH_MD5 3
|
#define RIP_AUTH_MD5 3
|
||||||
|
|
||||||
|
/* RIPv2 Simple authentication */
|
||||||
|
#define RIP_AUTH_SIMPLE_SIZE 16
|
||||||
|
|
||||||
/* RIPv2 MD5 authentication. */
|
/* RIPv2 MD5 authentication. */
|
||||||
#define RIP_AUTH_MD5_SIZE 16
|
#define RIP_AUTH_MD5_SIZE 16
|
||||||
#define RIP_AUTH_MD5_COMPAT_SIZE RIP_RTE_SIZE
|
#define RIP_AUTH_MD5_COMPAT_SIZE RIP_RTE_SIZE
|
||||||
|
Loading…
Reference in New Issue
Block a user