]>
git.ipfire.org Git - thirdparty/bird.git/blob - proto/rip/auth.c
b7b0611ee887de8c7a183d33c183af51a1930183
2 * Rest in pieces - RIP protocol
4 * Copyright (c) 1999 Pavel Machek <pavel@ucw.cz>
5 * Copyright (c) 2004 Ondrej Filip <feela@network.cz>
7 * Bug fixes by Eric Leblond <eleblond@init-sys.com>, April 2003
9 * Can be freely distributed and used under the terms of the GNU GPL.
14 #include "nest/bird.h"
15 #include "nest/iface.h"
16 #include "nest/protocol.h"
17 #include "nest/route.h"
18 #include "lib/socket.h"
19 #include "lib/resource.h"
20 #include "lib/lists.h"
21 #include "lib/timer.h"
23 #include "lib/string.h"
27 #define P ((struct rip_proto *) p)
28 #define P_CF ((struct rip_proto_config *)p->cf)
30 #define PACKETLEN(num) (num * sizeof(struct rip_block) + sizeof(struct rip_packet_heading))
33 * rip_incoming_authentication - check authentication of incomming packet and return 1 if there's problem.
36 rip_incoming_authentication( struct proto
*p
, struct rip_block_auth
*block
, struct rip_packet
*packet
, int num
, ip_addr whotoldme
)
38 DBG( "Incoming authentication: " );
39 switch (ntohs(block
->authtype
)) { /* Authentication type */
42 struct password_item
*passwd
= password_find(P_CF
->passwords
, 1);
43 DBG( "Plaintext passwd" );
45 log( L_AUTH
"No passwords set and password authentication came" );
48 if (strncmp( (char *) (&block
->packetlen
), passwd
->password
, 16)) {
49 log( L_AUTH
"Passwd authentication failed!" );
50 DBG( "Expected %s, got %.16s\n", passwd
->password
, &block
->packetlen
);
56 DBG( "md5 password" );
58 struct password_item
*pass
= NULL
, *ptmp
;
59 struct rip_md5_tail
*tail
;
60 struct MD5Context ctxt
;
61 char md5sum_packet
[16];
62 char md5sum_computed
[16];
63 struct neighbor
*neigh
= neigh_find(p
, &whotoldme
, 0);
64 list
*l
= P_CF
->passwords
;
66 if (ntohs(block
->packetlen
) != PACKETLEN(num
) - sizeof(struct rip_md5_tail
) ) {
67 log( L_ERR
"Packet length in MD5 does not match computed value" );
71 tail
= (struct rip_md5_tail
*) ((char *) packet
+ (ntohs(block
->packetlen
) ));
72 if ((tail
->mustbeFFFF
!= 0xffff) || (tail
->mustbe0001
!= 0x0100)) {
73 log( L_ERR
"MD5 tail signature is not there" );
79 if (block
->keyid
!= ptmp
->id
) continue;
80 if ((ptmp
->genfrom
> now_real
) || (ptmp
->gento
< now_real
)) continue;
88 log( L_AUTH
"Non-neighbour MD5 checksummed packet?" );
90 if (neigh
->aux
> block
->seq
) {
91 log( L_AUTH
"MD5 protected packet with lower numbers" );
94 neigh
->aux
= block
->seq
;
97 memcpy(md5sum_packet
, tail
->md5
, 16);
98 password_cpy(tail
->md5
, pass
->password
, 16);
101 MD5Update(&ctxt
, (char *) packet
, ntohs(block
->packetlen
) + sizeof(struct rip_block_auth
) );
102 MD5Final(md5sum_computed
, &ctxt
);
103 if (memcmp(md5sum_packet
, md5sum_computed
, 16))
112 * rip_outgoing_authentication - append authentication information to the packet.
113 * %num: number of rip_blocks already in packets. This function returns size of packet to send.
116 rip_outgoing_authentication( struct proto
*p
, struct rip_block_auth
*block
, struct rip_packet
*packet
, int num
)
118 struct password_item
*passwd
= password_find(P_CF
->passwords
, 1);
121 return PACKETLEN(num
);
123 DBG( "Outgoing authentication: " );
126 log( L_ERR
"No suitable password found for authentication" );
127 return PACKETLEN(num
);
130 block
->authtype
= htons(P_CF
->authtype
);
131 block
->mustbeFFFF
= 0xffff;
132 switch (P_CF
->authtype
) {
134 password_cpy( (char *) (&block
->packetlen
), passwd
->password
, 16);
135 return PACKETLEN(num
);
138 struct rip_md5_tail
*tail
;
139 struct MD5Context ctxt
;
140 static u32 sequence
= 0;
142 if (num
> PACKET_MD5_MAX
)
143 bug( "We can not add MD5 authentication to this long packet" );
145 /* need to preset the sequence number to a sane value */
147 sequence
= (u32
) time(NULL
);
149 block
->keyid
= passwd
->id
;
150 block
->authlen
= sizeof(struct rip_block_auth
);
151 block
->seq
= sequence
++;
154 block
->packetlen
= htons(PACKETLEN(num
));
155 tail
= (struct rip_md5_tail
*) ((char *) packet
+ PACKETLEN(num
) );
156 tail
->mustbeFFFF
= 0xffff;
157 tail
->mustbe0001
= 0x0100;
159 password_cpy(tail
->md5
, passwd
->password
, 16);
161 MD5Update(&ctxt
, (char *) packet
, PACKETLEN(num
) + sizeof(struct rip_md5_tail
));
162 MD5Final(tail
->md5
, &ctxt
);
163 return PACKETLEN(num
) + block
->authlen
;
166 bug( "Unknown authtype in outgoing authentication?" );