Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 202221
Collapse All | Expand All

(-)configure.ac (+9 lines)
Line 214 Link Here
214
AC_ARG_ENABLE(tcp-md5,
215
[  --enable-tcp-md5        enable TCP/IP md5 in BGPd])
Line 284 Link Here
286
Line 530 Link Here
533
534
if test "${enable_tcp_md5}" = "yes"; then
535
  if test x"$opsys" = x"gnu-linux"; then
536
    AC_DEFINE(HAVE_TCP_MD5SIG,1,Enable TCP Signing)
537
  fi
538
fi
(-)bgpd/bgp_network.c (+115 lines)
Line 25 Link Here
25
#include "sockopt.h"
Line 41 Link Here
42
#if defined(HAVE_TCP_MD5SIG)
43
/*
44
 * Set MD5 key for the socket, for the given IPv4 peer address.
45
 * If the password is NULL or zero-length, the option will be disabled.
46
 */
47
int
48
bgp_md5_set (int sock, struct sockaddr_in *sin, const char *password)
49
{
50
  int ret, en;
51
52
  if ( bgpd_privs.change (ZPRIVS_RAISE) )
53
    zlog_err ("bgp_md5_set: could not raise privs");
54
55
  ret = sockopt_tcp_signature (sock, sin, password);
56
  en  = errno;
57
58
  if (bgpd_privs.change (ZPRIVS_LOWER) )
59
    zlog_err ("bgp_md5_set: could not lower privs");
60
61
  if (ret < 0)
62
    zlog (NULL, LOG_WARNING, "can't set TCP_MD5SIG option on socket %d: %s",
63
	  sock, safe_strerror (en));
64
65
  return ret;
66
}
67
68
#endif /* HAVE_TCP_MD5SIG */
69
Line 241 Link Here
270
#ifdef HAVE_TCP_MD5SIG
271
  if (CHECK_FLAG (peer->flags, PEER_FLAG_PASSWORD))
272
    if (sockunion_family (&peer->su) == AF_INET)
273
      bgp_md5_set (peer->fd, &peer->su.sin, peer->password);
274
#endif /* HAVE_TCP_MD5SIG */
275
Line 291 Link Here
326
#if defined(HAVE_TCP_MD5SIG) && defined(IPV6_V6ONLY)
327
  struct sockaddr_in sin;
328
  int socklen, on = 1;
329
#endif
Line 326 Link Here
365
#if defined(HAVE_TCP_MD5SIG) && defined(IPV6_V6ONLY)
366
/*	We can not apply MD5SIG to an IPv6 socket.  If this is an AF_INET6
367
	socket, we'll have to create another socket for IPv4*/
368
369
      if (ainfo->ai_family == AF_INET6) {
370
/*	Mark this one for IPv6 only	*/
371
          ret = setsockopt (sock, IPPROTO_IPV6, IPV6_V6ONLY, 
372
		    (void *) &on, sizeof (on));
373
          if( ret < 0 ) {
374
              en = errno;
375
	      zlog_err ("setsockopt V6ONLY: %s", safe_strerror (en));
376
          }
377
      }
378
#endif
379
Line 349 Link Here
403
#if defined(HAVE_TCP_MD5SIG) && defined(IPV6_V6ONLY)
404
      thread_add_read (master, bgp_accept, bgp, sock);
405
406
      if (ainfo->ai_family != AF_INET6)
407
	continue;
408
     
409
      /* If first socket was an IPv6 socket, we need to create an IPv4
410
	socket for use by the TCP_MD5SIG logic.  This code is blatently
411
	copied and modified from the alternate IPv4 only code from below... */
412
413
      sock = socket (AF_INET, SOCK_STREAM, 0);
414
      if (sock < 0)
415
        {
416
          zlog_err ("socket: %s", safe_strerror (errno));
417
          continue;
418
        }
419
420
      sockopt_reuseaddr (sock);
421
      sockopt_reuseport (sock);
422
423
      memset (&sin, 0, sizeof (struct sockaddr_in));
424
425
      sin.sin_family = AF_INET;
426
      sin.sin_port = htons (port);
427
      socklen = sizeof (struct sockaddr_in);
428
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
429
      sin.sin_len = socklen;
430
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
431
432
      if ( bgpd_privs.change (ZPRIVS_RAISE) )
433
        zlog_err ("bgp_socket: could not raise privs");
434
435
      ret = bind (sock, (struct sockaddr *) &sin, socklen);
436
      en = errno;
437
      if (bgpd_privs.change (ZPRIVS_LOWER) )
438
	zlog_err ("bgp_bind_address: could not lower privs");
439
440
      if (ret < 0)
441
	{
442
	  zlog_err ("bind: %s", safe_strerror (en));
443
	  close(sock);
444
	  continue;
445
	}
446
      
447
      ret = listen (sock, 3);
448
      if (ret < 0) 
449
	{
450
	  zlog_err ("listen: %s", safe_strerror (errno));
451
	  close (sock);
452
	  continue;
453
	}
454
#endif
455
456
#ifdef HAVE_TCP_MD5SIG
457
      bm->sock = sock;
458
#endif /* HAVE_TCP_MD5SIG */
459
Line 350 Link Here
461
Line 409 Link Here
521
#ifdef HAVE_TCP_MD5SIG
522
  bm->sock = sock;
523
#endif /* HAVE_TCP_MD5SIG */
(-)bgpd/bgp_network.h (+4 lines)
Line 24 Link Here
24
#if defined(HAVE_TCP_MD5SIG) 
25
extern int bgp_md5_set (int, struct sockaddr_in *, const char *);
26
#endif /* HAVE_TCP_MD5SIG */
27
(-)bgpd/bgp_vty.c (+46 lines)
Line 1482 Link Here
1482
#ifdef HAVE_TCP_MD5SIG
1483
DEFUN (neighbor_password,
1484
       neighbor_password_cmd,
1485
       NEIGHBOR_CMD2 "password LINE",
1486
       NEIGHBOR_STR
1487
       NEIGHBOR_ADDR_STR2
1488
       "Set a password\n"
1489
       "The password\n")
1490
{
1491
  struct peer *peer;
1492
  int ret;
1493
1494
  peer = peer_and_group_lookup_vty (vty, argv[0]);
1495
  if (! peer)
1496
    return CMD_WARNING;
1497
1498
  ret = peer_password_set (peer, argv[1]);
1499
  return bgp_vty_return (vty, ret);
1500
}
1501
1502
DEFUN (no_neighbor_password,
1503
       no_neighbor_password_cmd,
1504
       NO_NEIGHBOR_CMD2 "password",
1505
       NO_STR
1506
       NEIGHBOR_STR
1507
       NEIGHBOR_ADDR_STR2
1508
       "Set a password\n")
1509
{
1510
  struct peer *peer;
1511
  int ret;
1512
1513
  peer = peer_and_group_lookup_vty (vty, argv[0]);
1514
  if (! peer)
1515
    return CMD_WARNING;
1516
1517
  ret = peer_password_unset (peer);
1518
  return bgp_vty_return (vty, ret);
1519
}
1520
#endif /* HAVE_TCP_MD5SIG */
1521
Line 8899 Link Here
8939
8940
#ifdef HAVE_TCP_MD5SIG
8941
  /* "neighbor password" commands. */
8942
  install_element (BGP_NODE, &neighbor_password_cmd);
8943
  install_element (BGP_NODE, &no_neighbor_password_cmd);
8944
#endif /* HAVE_TCP_MD5SIG */
(-)bgpd/bgpd.c (+168 lines)
Line 791 Link Here
791
  peer->password = NULL;
Line 1205 Link Here
1206
1207
#ifdef HAVE_TCP_MD5SIG
1208
  /* Password configuration */
1209
  if (peer->password)
1210
    {
1211
      free (peer->password);
1212
      peer->password = NULL;
1213
1214
      if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)
1215
          && sockunion_family (&peer->su) == AF_INET)
1216
       bgp_md5_set (bm->sock, &peer->su.sin, NULL);
1217
    }
1218
#endif /* HAVE_TCP_MD5SIG */
1219
 
Line 1420 Link Here
1435
#ifdef HAVE_TCP_MD5SIG
1436
  /* password apply */
1437
  if (CHECK_FLAG (conf->flags, PEER_FLAG_PASSWORD))
1438
    {
1439
      if (peer->password)
1440
	free (peer->password);
1441
      peer->password = strdup (conf->password);
1442
1443
      if (sockunion_family (&peer->su) == AF_INET)
1444
	bgp_md5_set (bm->sock, &peer->su.sin, peer->password);
1445
    }
1446
  else if (peer->password)
1447
    {
1448
      free (peer->password);
1449
      peer->password = NULL;
1450
1451
      if (sockunion_family (&peer->su) == AF_INET)
1452
        bgp_md5_set (bm->sock, &peer->su.sin, NULL);
1453
    }
1454
#endif /* HAVE_TCP_MD5SIG */
1455
Line 3382 Link Here
3418
#ifdef HAVE_TCP_MD5SIG
3419
/* Set password for authenticating with the peer. */
3420
int
3421
peer_password_set (struct peer *peer, const char *password)
3422
{
3423
  struct peer_group *group;
3424
  struct listnode *nn, *nnode;
3425
  int len = password ? strlen(password) : 0;
3426
3427
  if ((len < PEER_PASSWORD_MINLEN) || (len > PEER_PASSWORD_MAXLEN))
3428
    return BGP_ERR_INVALID_VALUE;
3429
3430
  if (peer->password && strcmp (peer->password, password) == 0
3431
      && ! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3432
	return 0;
3433
3434
  SET_FLAG (peer->flags, PEER_FLAG_PASSWORD);
3435
  if (peer->password)
3436
    free (peer->password);
3437
  peer->password = strdup (password);
3438
3439
  if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3440
    {
3441
      if (peer->status == Established)
3442
          bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3443
      else
3444
        BGP_EVENT_ADD (peer, BGP_Stop);
3445
3446
      if (sockunion_family (&peer->su) == AF_INET)
3447
	bgp_md5_set (bm->sock, &peer->su.sin, peer->password);
3448
      return 0;
3449
    }
3450
3451
  group = peer->group;
3452
  /* #42# LIST_LOOP (group->peer, peer, nn) */
3453
  for (ALL_LIST_ELEMENTS (group->peer, nn, nnode, peer))
3454
    {
3455
      if (peer->password && strcmp (peer->password, password) == 0)
3456
	continue;
3457
3458
      SET_FLAG (peer->flags, PEER_FLAG_PASSWORD);
3459
      if (peer->password)
3460
        free (peer->password);
3461
      peer->password = strdup (password);
3462
3463
      if (peer->status == Established)
3464
        bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3465
      else
3466
        BGP_EVENT_ADD (peer, BGP_Stop);
3467
3468
      if (sockunion_family (&peer->su) == AF_INET)
3469
	bgp_md5_set (bm->sock, &peer->su.sin, peer->password);
3470
    }
3471
3472
  return 0;
3473
}
3474
3475
int
3476
peer_password_unset (struct peer *peer)
3477
{
3478
  struct peer_group *group;
3479
  struct listnode *nn, *nnode;
3480
3481
  if (! CHECK_FLAG (peer->flags, PEER_FLAG_PASSWORD)
3482
      && ! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3483
    return 0;
3484
3485
  if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP))
3486
    {
3487
      if (peer_group_active (peer)
3488
	  && CHECK_FLAG (peer->group->conf->flags, PEER_FLAG_PASSWORD))
3489
	return BGP_ERR_PEER_GROUP_HAS_THE_FLAG;
3490
3491
      if (peer->status == Established)
3492
        bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3493
      else
3494
        BGP_EVENT_ADD (peer, BGP_Stop);
3495
3496
      if (sockunion_family (&peer->su) == AF_INET)
3497
	bgp_md5_set (bm->sock, &peer->su.sin, NULL);
3498
3499
      UNSET_FLAG (peer->flags, PEER_FLAG_PASSWORD);
3500
      if (peer->password)
3501
	free (peer->password);
3502
      peer->password = NULL;
3503
3504
      return 0;
3505
    }
3506
3507
  UNSET_FLAG (peer->flags, PEER_FLAG_PASSWORD);
3508
  if (peer->password)
3509
    free (peer->password);
3510
  peer->password = NULL;
3511
3512
  group = peer->group;
3513
  /* #42# LIST_LOOP (group->peer, peer, nn) */
3514
  for (ALL_LIST_ELEMENTS (group->peer, nn, nnode, peer))
3515
    {
3516
      if (! CHECK_FLAG (peer->flags, PEER_FLAG_PASSWORD))
3517
	continue;
3518
3519
      if (peer->status == Established)
3520
        bgp_notify_send (peer, BGP_NOTIFY_CEASE, BGP_NOTIFY_CEASE_CONFIG_CHANGE);
3521
      else
3522
        BGP_EVENT_ADD (peer, BGP_Stop);
3523
3524
      if (sockunion_family (&peer->su) == AF_INET)
3525
	bgp_md5_set (bm->sock, &peer->su.sin, NULL);
3526
3527
      UNSET_FLAG (peer->flags, PEER_FLAG_PASSWORD);
3528
      if (peer->password)
3529
        free (peer->password);
3530
      peer->password = NULL;
3531
    }
3532
3533
  return 0;
3534
}
3535
#endif /* HAVE_TCP_MD5SIG */
3536
Line 4419 Link Here
4574
#ifdef HAVE_TCP_MD5SIG
4575
      /* Password. */
4576
      if (CHECK_FLAG (peer->flags, PEER_FLAG_PASSWORD))
4577
	if (! peer_group_active (peer)
4578
	    || ! CHECK_FLAG (g_peer->flags, PEER_FLAG_PASSWORD)
4579
	    || strcmp (peer->password, g_peer->password) != 0)
4580
	  vty_out (vty, " neighbor %s password %s%s", addr, peer->password,
4581
		   VTY_NEWLINE);
4582
#endif /* HAVE_TCP_MD5SIG */
4583
Line 4954 Link Here
5119
#ifdef HAVE_TCP_MD5SIG
5120
  bm->sock = -1;
5121
#endif /* HAVE_TCP_MD5SIG */
(-)bgpd/bgpd.conf.sample (-26 / +10 lines)
Line 1 Link Here
1
! -*- bgp -*-
Lines 3-5 Link Here
3
! BGPd sample configuratin file
2
! Zebra configuration saved from vty
4
!
3
!   2007/10/23 00:16:48
5
! $Id: bgpd.conf.sample,v 1.1.1.1 2002/12/13 20:15:29 paul Exp $
6
--
Lines 9-21 Link Here
9
!enable password please-set-at-here
7
enable password zebra
10
!
8
log stdout
11
!bgp mulitple-instance
12
!
13
router bgp 7675
14
! bgp router-id 10.0.0.1
15
! network 10.0.0.0/8
16
! neighbor 10.0.0.2 remote-as 7675
17
! neighbor 10.0.0.2 route-map set-nexthop out
18
! neighbor 10.0.0.2 ebgp-multihop
19
! neighbor 10.0.0.2 next-hop-self
20
!
21
! access-list all permit any
22
--
Lines 23-25 Link Here
23
!route-map set-nexthop permit 10
10
router bgp 65502
24
! match ip address all
11
 bgp router-id 10.80.0.2
25
! set ip next-hop 10.0.0.1
12
 timers bgp 1 3
26
--
13
 neighbor 10.80.0.1 remote-as 65500
14
 neighbor 10.80.0.1 timers connect 1
Line 27 Link Here
27
!log file bgpd.log
16
line vty
28
--
Line 29 Link Here
29
log stdout
(-)bgpd/bgpd.h (+21 lines)
Line 56 Link Here
56
57
#ifdef HAVE_TCP_MD5SIG
58
  /* bgp receive socket */
59
  int sock;
60
#endif /* HAVE_TCP_MD5SIG */
Line 358 Link Here
363
#define PEER_FLAG_PASSWORD                  (1 << 9) /* password */
Line 379 Link Here
385
  /* MD5 password */
386
  char *password;
387
Line 534 Link Here
543
#if defined(HAVE_TCP_MD5SIG)
544
545
#define PEER_PASSWORD_MINLEN	(1)
546
#define PEER_PASSWORD_MAXLEN	(80)
547
548
#endif /* HAVE_TCP_MD5SIG */
549
Line 924 Link Here
940
#ifdef HAVE_TCP_MD5SIG
941
extern int peer_password_set (struct peer *, const char *);
942
extern int peer_password_unset (struct peer *);
943
#endif /* HAVE_TCP_MD5SIG */
944
(-)lib/sockopt.c (+33 lines)
Line 483 Link Here
483
484
#if defined(HAVE_TCP_MD5SIG)
485
int
486
sockopt_tcp_signature (int sock, struct sockaddr_in *sin, const char *password)
487
{
488
  int keylen = password ? strlen(password) : 0;
489
490
#if defined(GNU_LINUX)
491
492
  struct tcp_md5sig md5sig;
493
494
  bzero ((char *)&md5sig, sizeof(md5sig));
495
  memcpy (&md5sig.tcpm_addr, sin, sizeof(*sin));
496
  md5sig.tcpm_keylen = keylen;
497
  if (keylen)
498
    memcpy (md5sig.tcpm_key, password, keylen);
499
500
  return setsockopt (sock, IPPROTO_TCP, TCP_MD5SIG, &md5sig, sizeof md5sig);
501
502
#else /* !GNU_LINUX */
503
504
  int enable = keylen ? (TCP_SIG_SPI_BASE + sin->sin_port) : 0;
505
506
  /*
507
   * XXX Need to do PF_KEY operation here to add/remove an SA entry,
508
   * and add/remove an SP entry for this peer's packet flows also.
509
   */
510
  return setsockopt (sock, IPPROTO_TCP, TCP_MD5SIG, &enable,
511
		     sizeof(enable));
512
513
#endif /* !GNU_LINUX */
514
}
515
#endif /* HAVE_TCP_MD5SIG */
(-)lib/sockopt.h (+28 lines)
Line 101 Link Here
101
#if defined(HAVE_TCP_MD5SIG)
102
103
#if defined(GNU_LINUX) && !defined(TCP_MD5SIG)
104
105
/* XXX these will come from <linux/tcp.h> eventually */
106
107
#define TCP_MD5SIG		14
108
#define TCP_MD5SIG_MAXKEYLEN	80
109
110
struct tcp_md5sig {
111
        struct sockaddr_storage tcpm_addr;      /* address associated */
112
        __u16   __tcpm_pad1;                            /* zero */
113
        __u16   tcpm_keylen;                            /* key length */
114
        __u32   __tcpm_pad2;                            /* zero */
115
        __u8    tcpm_key[TCP_MD5SIG_MAXKEYLEN];         /* key (binary) */
116
};
117
118
#endif /* defined(GNU_LINUX) && !defined(TCP_MD5SIG) */
119
120
#if !defined(GNU_LINUX) && !defined(TCP_SIG_SPI_BASE)
121
#define TCP_SIG_SPI_BASE 1000 /* XXX this will go away */
122
#endif
123
124
extern int sockopt_tcp_signature(int sock, struct sockaddr_in *sin,
125
                                 const char *password);
126
127
#endif /* HAVE_TCP_MD5SIG */
128

Return to bug 202221