Statistics
| Branch: | Revision:

iof-bird-daemon / proto / rip / auth.c @ df49d4e1

History | View | Annotate | Download (4.26 KB)

1 1b16029c Pavel Machek
/*
2
 *        Rest in pieces - RIP protocol
3
 *
4
 *        Copyright (c) 1999 Pavel Machek <pavel@ucw.cz>
5
 *
6
 *        Can be freely distributed and used under the terms of the GNU GPL.
7
 */
8
9
#define LOCAL_DEBUG
10
11
#include "nest/bird.h"
12
#include "nest/iface.h"
13
#include "nest/protocol.h"
14
#include "nest/route.h"
15
#include "lib/socket.h"
16
#include "lib/resource.h"
17
#include "lib/lists.h"
18
#include "lib/timer.h"
19 91c7c741 Pavel Machek
#include "lib/md5.h"
20 221135d6 Martin Mares
#include "lib/string.h"
21 1b16029c Pavel Machek
22
#include "rip.h"
23
24
#define P ((struct rip_proto *) p)
25
#define P_CF ((struct rip_proto_config *)p->cf)
26
27 29818140 Pavel Machek
#define PACKETLEN(num) (num * sizeof(struct rip_block) + sizeof(struct rip_packet_heading))
28
29 10915c96 Pavel Machek
/* 1 == failed, 0 == ok */
30 1b16029c Pavel Machek
int
31 639e6285 Pavel Machek
rip_incoming_authentication( struct proto *p, struct rip_block_auth *block, struct rip_packet *packet, int num, ip_addr whotoldme )
32 1b16029c Pavel Machek
{
33
  DBG( "Incoming authentication: " );
34 10915c96 Pavel Machek
  switch (block->authtype) {        /* Authentication type */
35 d3702d57 Pavel Machek
  case AT_PLAINTEXT: 
36
    {
37
      struct password_item *passwd = get_best_password( P_CF->passwords, 0 );
38
      DBG( "Plaintext passwd" );
39
      if (!passwd) {
40 df49d4e1 Martin Mares
        log( L_AUTH "No passwords set and password authentication came" );
41 d3702d57 Pavel Machek
        return 1;
42
      }
43
      if (strncmp( (char *) (&block->packetlen), passwd->password, 16)) {
44 df49d4e1 Martin Mares
        log( L_AUTH "Passwd authentication failed!" );
45 d3702d57 Pavel Machek
        DBG( "Expected %s, got %s\n", passwd->password, &block->packetlen );
46
        return 1;
47
      }
48 1b16029c Pavel Machek
    }
49
    return 0;
50 10915c96 Pavel Machek
  case AT_MD5:
51
    DBG( "md5 password" );
52
    {
53
      struct password_item *head;
54 91c7c741 Pavel Machek
      struct rip_md5_tail *tail;
55
56 1a509a63 Pavel Machek
      if (block->packetlen != PACKETLEN(num)) {
57 df49d4e1 Martin Mares
        log( L_ERR "Packet length in MD5 does not match computed value" );
58 29818140 Pavel Machek
        return 1;
59
      }
60 bce8a34b Pavel Machek
61 bf97bd28 Pavel Machek
      tail = (struct rip_md5_tail *) ((char *) packet + (block->packetlen - sizeof(struct rip_block_auth)));
62 d3702d57 Pavel Machek
      if ((tail->mustbeFFFF != 0xffff) || (tail->mustbe0001 != 0x0001)) {
63 df49d4e1 Martin Mares
        log( L_ERR "MD5 tail signature is not there" );
64 d3702d57 Pavel Machek
        return 1;
65
      }
66 91c7c741 Pavel Machek
67 10915c96 Pavel Machek
      head = P_CF->passwords;
68 29818140 Pavel Machek
      while (head) {
69 ac40c888 Pavel Machek
        DBG( "time, " );
70 29818140 Pavel Machek
        if ((head->from > now) || (head->to < now))
71 ac40c888 Pavel Machek
          goto skip;
72 639e6285 Pavel Machek
        if (block->seq) {
73
          struct neighbor *neigh = neigh_find(p, &whotoldme, 0);
74
          if (!neigh) {
75 df49d4e1 Martin Mares
            log( L_AUTH "Non-neighbour MD5 checksummed packet?" );
76 639e6285 Pavel Machek
          } else {
77
            if (neigh->aux > block->seq) {
78 df49d4e1 Martin Mares
              log( L_AUTH "MD5 protected packet with lower numbers" );
79 639e6285 Pavel Machek
              return 0;
80
            }
81
            neigh->aux = block->seq;
82
          }
83
        }
84 ac40c888 Pavel Machek
        DBG( "check, " );
85 91c7c741 Pavel Machek
        if (head->id == block->keyid) {
86
          struct MD5Context ctxt;
87
          char md5sum_packet[16];
88
          char md5sum_computed[16];
89
90 bf97bd28 Pavel Machek
          memcpy(md5sum_packet, tail->md5, 16);
91 91c7c741 Pavel Machek
          password_strncpy(tail->md5, head->password, 16);
92
93
          MD5Init(&ctxt);
94 bf97bd28 Pavel Machek
          MD5Update(&ctxt, (char *) packet, block->packetlen );
95 91c7c741 Pavel Machek
          MD5Final(md5sum_computed, &ctxt);
96
97
          if (memcmp(md5sum_packet, md5sum_computed, 16))
98
            return 1;
99 ac40c888 Pavel Machek
          return 0;
100 91c7c741 Pavel Machek
        }
101 ac40c888 Pavel Machek
      skip:
102 10915c96 Pavel Machek
        head = head->next;
103
      }
104
      return 1;
105
    }
106 1b16029c Pavel Machek
  }
107
    
108
  return 0;
109
}
110
111 d3702d57 Pavel Machek
int
112 10915c96 Pavel Machek
rip_outgoing_authentication( struct proto *p, struct rip_block_auth *block, struct rip_packet *packet, int num )
113 1b16029c Pavel Machek
{
114 bce8a34b Pavel Machek
  struct password_item *passwd = get_best_password( P_CF->passwords, 0 );
115 d3702d57 Pavel Machek
116
  if (!P_CF->authtype)
117
    return PACKETLEN(num);
118
119 1b16029c Pavel Machek
  DBG( "Outgoing authentication: " );
120
121 bce8a34b Pavel Machek
  if (!passwd) {
122 df49d4e1 Martin Mares
    log( L_ERR "No suitable password found for authentication" );
123 d3702d57 Pavel Machek
    return PACKETLEN(num);
124 bce8a34b Pavel Machek
  }
125
126 10915c96 Pavel Machek
  block->authtype = P_CF->authtype;
127 bce8a34b Pavel Machek
  block->mustbeFFFF = 0xffff;
128 1b16029c Pavel Machek
  switch (P_CF->authtype) {
129
  case AT_PLAINTEXT:
130 bce8a34b Pavel Machek
    password_strncpy( (char *) (&block->packetlen), passwd->password, 16);
131 d3702d57 Pavel Machek
    return PACKETLEN(num);
132 bce8a34b Pavel Machek
  case AT_MD5:
133
    {
134
      struct rip_md5_tail *tail;
135
      struct MD5Context ctxt;
136
      static int sequence = 0;
137
138
      if (num > PACKET_MD5_MAX)
139 df49d4e1 Martin Mares
        bug(  "We can not add MD5 authentication to this long packet" );
140 bce8a34b Pavel Machek
141
      block->keyid = passwd->id;
142
      block->authlen = 20;
143
      block->seq = sequence++;
144
      block->zero0 = 0;
145 d3702d57 Pavel Machek
      block->zero1 = 0;
146
      block->packetlen = PACKETLEN(num) + block->authlen;
147 bce8a34b Pavel Machek
148
      tail = (struct rip_md5_tail *) ((char *) packet + (block->packetlen - sizeof(struct rip_block_auth)));
149
      tail->mustbeFFFF = 0xffff;
150
      tail->mustbe0001 = 0x0001;
151
      password_strncpy( (char *) (&tail->md5), passwd->password, 16 );
152
153
      MD5Init(&ctxt);
154
      MD5Update(&ctxt, (char *) packet, block->packetlen );
155
      MD5Final((char *) (&tail->md5), &ctxt);
156 1a509a63 Pavel Machek
      return PACKETLEN(num) + block->authlen;
157 10915c96 Pavel Machek
    }
158 d3702d57 Pavel Machek
  default:
159 df49d4e1 Martin Mares
    bug( "Unknown authtype in outgoing authentication?" );
160 1b16029c Pavel Machek
  }
161
}