1
#! /bin/sh /usr/share/dpatch/dpatch-run
2
## 99-unnamed.dpatch by <ch@debian.org>
4
## All lines beginning with `## DP:' are a description of the patch.
5
## DP: [quagga-users 9315] New md5 signature patch for bgp... quagga_md5_bsd_linux_v9.diff
6
## DP: http://www.wittsend.com/mhw/md5sig/quagga_md5_bsd_linux_v9.diff
7
## DP: Removed configure.ac part and replaced with corresponding diff to configure
8
## DP: as that works better for the Debian build process which does not run aclocal.
12
diff -ruN quagga-0.99.9/bgpd/bgpd.c quagga-0.99.9-v9/bgpd/bgpd.c
13
--- quagga-0.99.9/bgpd/bgpd.c 2007-07-25 12:49:06.000000000 -0400
14
+++ quagga-0.99.9-v9/bgpd/bgpd.c 2007-09-24 20:28:55.000000000 -0400
19
+ peer->password = NULL;
21
peer = peer_lock (peer); /* initial reference */
23
@@ -1202,6 +1203,20 @@
24
peer->last_reset = PEER_DOWN_NEIGHBOR_DELETE;
26
bgp_fsm_change_status (peer, Deleted);
28
+#ifdef HAVE_TCP_MD5SIG
29
+ /* Password configuration */
32
+ free (peer->password);
33
+ peer->password = NULL;
35
+ if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)
36
+ && sockunion_family (&peer->su) == AF_INET)
37
+ bgp_md5_set (bm->sock, &peer->su.sin, NULL);
39
+#endif /* HAVE_TCP_MD5SIG */
41
bgp_timer_set (peer); /* stops all timers for Deleted */
43
/* Delete from all peer list. */
44
@@ -1417,6 +1432,27 @@
46
peer->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV;
48
+#ifdef HAVE_TCP_MD5SIG
49
+ /* password apply */
50
+ if (CHECK_FLAG (conf->flags, PEER_FLAG_PASSWORD))
53
+ free (peer->password);
54
+ peer->password = strdup (conf->password);
56
+ if (sockunion_family (&peer->su) == AF_INET)
57
+ bgp_md5_set (bm->sock, &peer->su.sin, peer->password);
59
+ else if (peer->password)
61
+ free (peer->password);
62
+ peer->password = NULL;
64
+ if (sockunion_family (&peer->su) == AF_INET)
65
+ bgp_md5_set (bm->sock, &peer->su.sin, NULL);
67
+#endif /* HAVE_TCP_MD5SIG */
70
peer->pmax[afi][safi] = conf->pmax[afi][safi];
71
peer->pmax_threshold[afi][safi] = conf->pmax_threshold[afi][safi];
72
@@ -3379,6 +3415,125 @@
76
+#ifdef HAVE_TCP_MD5SIG
77
+/* Set password for authenticating with the peer. */
79
+peer_password_set (struct peer *peer, const char *password)
81
+ struct peer_group *group;
82
+ struct listnode *nn, *nnode;
83
+ int len = password ? strlen(password) : 0;
85
+ if ((len < PEER_PASSWORD_MINLEN) || (len > PEER_PASSWORD_MAXLEN))
86
+ return BGP_ERR_INVALID_VALUE;
88
+ if (peer->password && strcmp (peer->password, password) == 0
89
+ && ! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
92
+ SET_FLAG (peer->flags, PEER_FLAG_PASSWORD);
94
+ free (peer->password);
95
+ peer->password = strdup (password);
97
+ if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
99
+ if (peer->status == Established)
100
+ bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
102
+ BGP_EVENT_ADD (peer, BGP_Stop);
104
+ if (sockunion_family (&peer->su) == AF_INET)
105
+ bgp_md5_set (bm->sock, &peer->su.sin, peer->password);
109
+ group = peer->group;
110
+ /* #42# LIST_LOOP (group->peer, peer, nn) */
111
+ for (ALL_LIST_ELEMENTS (group->peer, nn, nnode, peer))
113
+ if (peer->password && strcmp (peer->password, password) == 0)
116
+ SET_FLAG (peer->flags, PEER_FLAG_PASSWORD);
117
+ if (peer->password)
118
+ free (peer->password);
119
+ peer->password = strdup (password);
121
+ if (peer->status == Established)
122
+ bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
124
+ BGP_EVENT_ADD (peer, BGP_Stop);
126
+ if (sockunion_family (&peer->su) == AF_INET)
127
+ bgp_md5_set (bm->sock, &peer->su.sin, peer->password);
134
+peer_password_unset (struct peer *peer)
136
+ struct peer_group *group;
137
+ struct listnode *nn, *nnode;
139
+ if (! CHECK_FLAG (peer->flags, PEER_FLAG_PASSWORD)
140
+ && ! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
143
+ if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
145
+ if (peer_group_active (peer)
146
+ && CHECK_FLAG (peer->group->conf->flags, PEER_FLAG_PASSWORD))
147
+ return BGP_ERR_PEER_GROUP_HAS_THE_FLAG;
149
+ if (peer->status == Established)
150
+ bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
152
+ BGP_EVENT_ADD (peer, BGP_Stop);
154
+ if (sockunion_family (&peer->su) == AF_INET)
155
+ bgp_md5_set (bm->sock, &peer->su.sin, NULL);
157
+ UNSET_FLAG (peer->flags, PEER_FLAG_PASSWORD);
158
+ if (peer->password)
159
+ free (peer->password);
160
+ peer->password = NULL;
165
+ UNSET_FLAG (peer->flags, PEER_FLAG_PASSWORD);
166
+ if (peer->password)
167
+ free (peer->password);
168
+ peer->password = NULL;
170
+ group = peer->group;
171
+ /* #42# LIST_LOOP (group->peer, peer, nn) */
172
+ for (ALL_LIST_ELEMENTS (group->peer, nn, nnode, peer))
174
+ if (! CHECK_FLAG (peer->flags, PEER_FLAG_PASSWORD))
177
+ if (peer->status == Established)
178
+ bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
180
+ BGP_EVENT_ADD (peer, BGP_Stop);
182
+ if (sockunion_family (&peer->su) == AF_INET)
183
+ bgp_md5_set (bm->sock, &peer->su.sin, NULL);
185
+ UNSET_FLAG (peer->flags, PEER_FLAG_PASSWORD);
186
+ if (peer->password)
187
+ free (peer->password);
188
+ peer->password = NULL;
193
+#endif /* HAVE_TCP_MD5SIG */
195
/* Set distribute list to the peer. */
197
peer_distribute_set (struct peer *peer, afi_t afi, safi_t safi, int direct,
198
@@ -4416,6 +4571,16 @@
199
! CHECK_FLAG (g_peer->flags, PEER_FLAG_SHUTDOWN))
200
vty_out (vty, " neighbor %s shutdown%s", addr, VTY_NEWLINE);
202
+#ifdef HAVE_TCP_MD5SIG
204
+ if (CHECK_FLAG (peer->flags, PEER_FLAG_PASSWORD))
205
+ if (! peer_group_active (peer)
206
+ || ! CHECK_FLAG (g_peer->flags, PEER_FLAG_PASSWORD)
207
+ || strcmp (peer->password, g_peer->password) != 0)
208
+ vty_out (vty, " neighbor %s password %s%s", addr, peer->password,
210
+#endif /* HAVE_TCP_MD5SIG */
213
if (peer->port != BGP_PORT_DEFAULT)
214
vty_out (vty, " neighbor %s port %d%s", addr, peer->port,
215
@@ -4951,6 +5116,9 @@
216
bm->port = BGP_PORT_DEFAULT;
217
bm->master = thread_master_create ();
218
bm->start_time = time (NULL);
219
+#ifdef HAVE_TCP_MD5SIG
221
+#endif /* HAVE_TCP_MD5SIG */
225
diff -ruN quagga-0.99.9/bgpd/bgpd.h quagga-0.99.9-v9/bgpd/bgpd.h
226
--- quagga-0.99.9/bgpd/bgpd.h 2007-08-06 11:22:43.000000000 -0400
227
+++ quagga-0.99.9-v9/bgpd/bgpd.h 2007-09-24 20:28:55.000000000 -0400
229
#define BGP_OPT_NO_FIB (1 << 0)
230
#define BGP_OPT_MULTIPLE_INSTANCE (1 << 1)
231
#define BGP_OPT_CONFIG_CISCO (1 << 2)
233
+#ifdef HAVE_TCP_MD5SIG
234
+ /* bgp receive socket */
236
+#endif /* HAVE_TCP_MD5SIG */
239
/* BGP instance structure. */
242
/* NSF mode (graceful restart) */
243
u_char nsf[AFI_MAX][SAFI_MAX];
244
+#define PEER_FLAG_PASSWORD (1 << 9) /* password */
246
/* Per AF configuration flags. */
247
u_int32_t af_flags[AFI_MAX][SAFI_MAX];
249
#define PEER_FLAG_MAX_PREFIX_WARNING (1 << 15) /* maximum prefix warning-only */
250
#define PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED (1 << 16) /* leave link-local nexthop unchanged */
255
/* default-originate route-map. */
259
#define PEER_RMAP_TYPE_EXPORT (1 << 7) /* neighbor route-map export */
262
+#if defined(HAVE_TCP_MD5SIG)
264
+#define PEER_PASSWORD_MINLEN (1)
265
+#define PEER_PASSWORD_MAXLEN (80)
267
+#endif /* HAVE_TCP_MD5SIG */
269
/* This structure's member directly points incoming packet data
273
extern int peer_route_map_unset (struct peer *, afi_t, safi_t, int);
275
extern int peer_unsuppress_map_set (struct peer *, afi_t, safi_t, const char *);
276
+#ifdef HAVE_TCP_MD5SIG
277
+extern int peer_password_set (struct peer *, const char *);
278
+extern int peer_password_unset (struct peer *);
279
+#endif /* HAVE_TCP_MD5SIG */
281
extern int peer_unsuppress_map_unset (struct peer *, afi_t, safi_t);
283
extern int peer_maximum_prefix_set (struct peer *, afi_t, safi_t, u_int32_t, u_char, int, u_int16_t);
284
diff -ruN quagga-0.99.9/bgpd/bgp_network.c quagga-0.99.9-v9/bgpd/bgp_network.c
285
--- quagga-0.99.9/bgpd/bgp_network.c 2007-05-09 16:59:33.000000000 -0400
286
+++ quagga-0.99.9-v9/bgpd/bgp_network.c 2007-09-27 18:50:49.000000000 -0400
290
#include "sockunion.h"
291
+#include "sockopt.h"
296
extern struct zebra_privs_t bgpd_privs;
299
+#if defined(HAVE_TCP_MD5SIG)
301
+ * Set MD5 key for the socket, for the given IPv4 peer address.
302
+ * If the password is NULL or zero-length, the option will be disabled.
305
+bgp_md5_set (int sock, struct sockaddr_in *sin, const char *password)
309
+ if ( bgpd_privs.change (ZPRIVS_RAISE) )
310
+ zlog_err ("bgp_md5_set: could not raise privs");
312
+ ret = sockopt_tcp_signature (sock, sin, password);
315
+ if (bgpd_privs.change (ZPRIVS_LOWER) )
316
+ zlog_err ("bgp_md5_set: could not lower privs");
319
+ zlog (NULL, LOG_WARNING, "can't set TCP_MD5SIG option on socket %d: %s",
320
+ sock, safe_strerror (en));
325
+#endif /* HAVE_TCP_MD5SIG */
327
/* Accept bgp connection. */
329
bgp_accept (struct thread *thread)
331
sockopt_reuseaddr (peer->fd);
332
sockopt_reuseport (peer->fd);
334
+#ifdef HAVE_TCP_MD5SIG
335
+ if (CHECK_FLAG (peer->flags, PEER_FLAG_PASSWORD))
336
+ if (sockunion_family (&peer->su) == AF_INET)
337
+ bgp_md5_set (peer->fd, &peer->su.sin, peer->password);
338
+#endif /* HAVE_TCP_MD5SIG */
345
struct addrinfo *ainfo;
346
struct addrinfo *ainfo_save;
347
+#if defined(HAVE_TCP_MD5SIG) && defined(IPV6_V6ONLY)
348
+ struct sockaddr_in sin;
349
+ int socklen, on = 1;
352
char port_str[BUFSIZ];
355
sockopt_reuseaddr (sock);
356
sockopt_reuseport (sock);
358
+#if defined(HAVE_TCP_MD5SIG) && defined(IPV6_V6ONLY)
359
+/* We can not apply MD5SIG to an IPv6 socket. If this is an AF_INET6
360
+ socket, we'll have to create another socket for IPv4*/
362
+ if (ainfo->ai_family == AF_INET6) {
363
+/* Mark this one for IPv6 only */
364
+ ret = setsockopt (sock, IPPROTO_IPV6, IPV6_V6ONLY,
365
+ (void *) &on, sizeof (on));
368
+ zlog_err ("setsockopt V6ONLY: %s", safe_strerror (en));
373
if (bgpd_privs.change (ZPRIVS_RAISE) )
374
zlog_err ("bgp_socket: could not raise privs");
380
+#if defined(HAVE_TCP_MD5SIG) && defined(IPV6_V6ONLY)
381
+ thread_add_read (master, bgp_accept, bgp, sock);
383
+ if (ainfo->ai_family != AF_INET6)
386
+ /* If first socket was an IPv6 socket, we need to create an IPv4
387
+ socket for use by the TCP_MD5SIG logic. This code is blatently
388
+ copied and modified from the alternate IPv4 only code from below... */
390
+ sock = socket (AF_INET, SOCK_STREAM, 0);
393
+ zlog_err ("socket: %s", safe_strerror (errno));
397
+ sockopt_reuseaddr (sock);
398
+ sockopt_reuseport (sock);
400
+ memset (&sin, 0, sizeof (struct sockaddr_in));
402
+ sin.sin_family = AF_INET;
403
+ sin.sin_port = htons (port);
404
+ socklen = sizeof (struct sockaddr_in);
405
+#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
406
+ sin.sin_len = socklen;
407
+#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
409
+ if ( bgpd_privs.change (ZPRIVS_RAISE) )
410
+ zlog_err ("bgp_socket: could not raise privs");
412
+ ret = bind (sock, (struct sockaddr *) &sin, socklen);
414
+ if (bgpd_privs.change (ZPRIVS_LOWER) )
415
+ zlog_err ("bgp_bind_address: could not lower privs");
419
+ zlog_err ("bind: %s", safe_strerror (en));
424
+ ret = listen (sock, 3);
427
+ zlog_err ("listen: %s", safe_strerror (errno));
433
+#ifdef HAVE_TCP_MD5SIG
435
+#endif /* HAVE_TCP_MD5SIG */
437
thread_add_read (master, bgp_accept, bgp, sock);
440
while ((ainfo = ainfo->ai_next) != NULL);
446
+#ifdef HAVE_TCP_MD5SIG
448
+#endif /* HAVE_TCP_MD5SIG */
450
thread_add_read (bm->master, bgp_accept, bgp, sock);
452
diff -ruN quagga-0.99.9/bgpd/bgp_network.h quagga-0.99.9-v9/bgpd/bgp_network.h
453
--- quagga-0.99.9/bgpd/bgp_network.h 2007-06-29 09:41:43.000000000 -0400
454
+++ quagga-0.99.9-v9/bgpd/bgp_network.h 2007-09-24 20:28:55.000000000 -0400
456
#ifndef _QUAGGA_BGP_NETWORK_H
457
#define _QUAGGA_BGP_NETWORK_H
459
+#if defined(HAVE_TCP_MD5SIG)
460
+extern int bgp_md5_set (int, struct sockaddr_in *, const char *);
461
+#endif /* HAVE_TCP_MD5SIG */
463
extern int bgp_socket (struct bgp *, unsigned short);
464
extern int bgp_connect (struct peer *);
465
extern void bgp_getsockname (struct peer *);
466
diff -ruN quagga-0.99.9/bgpd/bgp_vty.c quagga-0.99.9-v9/bgpd/bgp_vty.c
467
--- quagga-0.99.9/bgpd/bgp_vty.c 2007-08-06 11:17:46.000000000 -0400
468
+++ quagga-0.99.9-v9/bgpd/bgp_vty.c 2007-09-24 20:28:55.000000000 -0400
469
@@ -1479,6 +1479,46 @@
470
"AS number used as local AS\n"
471
"Do not prepend local-as to updates from ebgp peers\n")
473
+#ifdef HAVE_TCP_MD5SIG
474
+DEFUN (neighbor_password,
475
+ neighbor_password_cmd,
476
+ NEIGHBOR_CMD2 "password LINE",
485
+ peer = peer_and_group_lookup_vty (vty, argv[0]);
487
+ return CMD_WARNING;
489
+ ret = peer_password_set (peer, argv[1]);
490
+ return bgp_vty_return (vty, ret);
493
+DEFUN (no_neighbor_password,
494
+ no_neighbor_password_cmd,
495
+ NO_NEIGHBOR_CMD2 "password",
499
+ "Set a password\n")
504
+ peer = peer_and_group_lookup_vty (vty, argv[0]);
506
+ return CMD_WARNING;
508
+ ret = peer_password_unset (peer);
509
+ return bgp_vty_return (vty, ret);
511
+#endif /* HAVE_TCP_MD5SIG */
513
DEFUN (neighbor_activate,
514
neighbor_activate_cmd,
515
NEIGHBOR_CMD2 "activate",
516
@@ -8894,6 +8934,12 @@
517
install_element (BGP_NODE, &no_neighbor_local_as_val_cmd);
518
install_element (BGP_NODE, &no_neighbor_local_as_val2_cmd);
520
+#ifdef HAVE_TCP_MD5SIG
521
+ /* "neighbor password" commands. */
522
+ install_element (BGP_NODE, &neighbor_password_cmd);
523
+ install_element (BGP_NODE, &no_neighbor_password_cmd);
524
+#endif /* HAVE_TCP_MD5SIG */
526
/* "neighbor activate" commands. */
527
install_element (BGP_NODE, &neighbor_activate_cmd);
528
install_element (BGP_IPV4_NODE, &neighbor_activate_cmd);
529
diff -ruN quagga-0.99.9/config.h.in quagga-0.99.9-v9/config.h.in
530
--- quagga-0.99.9/config.h.in 2007-09-07 12:56:20.000000000 -0400
531
+++ quagga-0.99.9-v9/config.h.in 2008-01-28 13:47:20.000000000 -0500
533
/* Use TCP for zebra communication */
534
#undef HAVE_TCP_ZEBRA
536
+/* Define to 1 for TCP MD5 Signatures */
537
+#undef HAVE_TCP_MD5SIG
539
/* Define to 1 if you have the <ucontext.h> header file. */
540
#undef HAVE_UCONTEXT_H
542
diff -ruN quagga-0.99.9/lib/sockopt.c quagga-0.99.9-v9/lib/sockopt.c
543
--- quagga-0.99.9/lib/sockopt.c 2007-08-22 12:22:54.000000000 -0400
544
+++ quagga-0.99.9-v9/lib/sockopt.c 2007-09-24 20:28:55.000000000 -0400
547
iph->ip_id = ntohs(iph->ip_id);
550
+#if defined(HAVE_TCP_MD5SIG)
552
+sockopt_tcp_signature (int sock, struct sockaddr_in *sin, const char *password)
554
+ int keylen = password ? strlen(password) : 0;
556
+#if defined(GNU_LINUX)
558
+ struct tcp_md5sig md5sig;
560
+ bzero ((char *)&md5sig, sizeof(md5sig));
561
+ memcpy (&md5sig.tcpm_addr, sin, sizeof(*sin));
562
+ md5sig.tcpm_keylen = keylen;
564
+ memcpy (md5sig.tcpm_key, password, keylen);
566
+ return setsockopt (sock, IPPROTO_TCP, TCP_MD5SIG, &md5sig, sizeof md5sig);
568
+#else /* !GNU_LINUX */
570
+ int enable = keylen ? (TCP_SIG_SPI_BASE + sin->sin_port) : 0;
573
+ * XXX Need to do PF_KEY operation here to add/remove an SA entry,
574
+ * and add/remove an SP entry for this peer's packet flows also.
576
+ return setsockopt (sock, IPPROTO_TCP, TCP_MD5SIG, &enable,
579
+#endif /* !GNU_LINUX */
581
+#endif /* HAVE_TCP_MD5SIG */
582
diff -ruN quagga-0.99.9/lib/sockopt.h quagga-0.99.9-v9/lib/sockopt.h
583
--- quagga-0.99.9/lib/sockopt.h 2007-08-22 12:22:54.000000000 -0400
584
+++ quagga-0.99.9-v9/lib/sockopt.h 2007-09-24 20:28:55.000000000 -0400
586
extern void sockopt_iphdrincl_swab_htosys (struct ip *iph);
587
extern void sockopt_iphdrincl_swab_systoh (struct ip *iph);
589
+#if defined(HAVE_TCP_MD5SIG)
591
+#if defined(GNU_LINUX) && !defined(TCP_MD5SIG)
593
+/* XXX these will come from <linux/tcp.h> eventually */
595
+#define TCP_MD5SIG 14
596
+#define TCP_MD5SIG_MAXKEYLEN 80
599
+ struct sockaddr_storage tcpm_addr; /* address associated */
600
+ __u16 __tcpm_pad1; /* zero */
601
+ __u16 tcpm_keylen; /* key length */
602
+ __u32 __tcpm_pad2; /* zero */
603
+ __u8 tcpm_key[TCP_MD5SIG_MAXKEYLEN]; /* key (binary) */
606
+#endif /* defined(GNU_LINUX) && !defined(TCP_MD5SIG) */
608
+#if !defined(GNU_LINUX) && !defined(TCP_SIG_SPI_BASE)
609
+#define TCP_SIG_SPI_BASE 1000 /* XXX this will go away */
612
+extern int sockopt_tcp_signature(int sock, struct sockaddr_in *sin,
613
+ const char *password);
615
+#endif /* HAVE_TCP_MD5SIG */
617
#endif /*_ZEBRA_SOCKOPT_H */
618
--- old/configure 2008-01-29 20:34:58.000000000 +0100
619
+++ new/configure 2008-01-29 20:34:10.000000000 +0100
620
@@ -1528,6 +1528,7 @@
621
--enable-broken-aliases enable aliases as distinct interfaces for Linux 2.2.X
622
--enable-snmp enable SNMP support
623
--enable-tcp-zebra enable TCP/IP socket connection between zebra and protocol daemon
624
+ --enable-tcp-md5 enable TCP/IP md5 in BGPd
625
--enable-opaque-lsa enable OSPF Opaque-LSA with OSPFAPI support (RFC2370)
626
--disable-ospfapi do not build OSPFAPI to access the OSPF LSA Database,
627
(this is the default if --enable-opaque-lsa is not set)
628
@@ -10843,6 +10844,11 @@
629
enableval=$enable_tcp_zebra;
632
+# Check whether --enable-tcp-md5 was given.
633
+if test "${enable_tcp_md5+set}" = set; then
634
+ enableval=$enable_tcp_md5;
637
# Check whether --enable-opaque-lsa was given.
638
if test "${enable_opaque_lsa+set}" = set; then
639
enableval=$enable_opaque_lsa;
640
@@ -10982,6 +10988,14 @@
644
+if test "${enable_tcp_md5}" = "yes"; then
646
+cat >>confdefs.h <<\_ACEOF
647
+#define HAVE_TCP_MD5SIG 1
652
if test "${enable_opaque_lsa}" = "yes"; then
654
cat >>confdefs.h <<\_ACEOF