File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / bird / sysdep / bsd / setkey.h
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Mar 17 19:50:23 2021 UTC (4 years ago) by misho
Branches: bird, MAIN
CVS tags: v1_6_8p3, HEAD
bird 1.6.8

    1: /*
    2:  *	BIRD -- Manipulation the IPsec SA/SP database using setkey(8) utility
    3:  *
    4:  * 	(c) 2016 CZ.NIC z.s.p.o.
    5:  */
    6: 
    7: #include <unistd.h>
    8: #include <sys/types.h>
    9: #include <sys/socket.h>
   10: #include <net/pfkeyv2.h>
   11: #include <netipsec/ipsec.h>
   12: 
   13: #include "nest/bird.h"
   14: #include "lib/unix.h"
   15: 
   16: 
   17: /*
   18:  * Open a socket for manage the IPsec SA/SP database entries
   19:  */
   20: static int
   21: setkey_open_socket(void)
   22: {
   23:   int s = socket(PF_KEY, SOCK_RAW, PF_KEY_V2);
   24:   if (s < 0)
   25:   {
   26:     log(L_ERR "SETKEY: socket: %m");
   27:     return -1;
   28:   }
   29: 
   30:   return s;
   31: }
   32: 
   33: static int
   34: setkey_send(struct sadb_msg *msg, uint len)
   35: {
   36:   int s = setkey_open_socket();
   37:   if (s < 0)
   38:     return -1;
   39: 
   40:   if (msg->sadb_msg_type == SADB_ADD)
   41:   {
   42:     /* Delete possible current key in the IPsec SA/SP database */
   43:     msg->sadb_msg_type = SADB_DELETE;
   44:     send(s, msg, len, 0);
   45:     msg->sadb_msg_type = SADB_ADD;
   46:   }
   47: 
   48:   if (send(s, msg, len, 0) < 0)
   49:   {
   50:     log(L_ERR "SETKEY: send: %m");
   51:     close(s);
   52:     return -1;
   53:   }
   54: 
   55:   close(s);
   56:   return 0;
   57: }
   58: 
   59: /*
   60:  * Perform setkey(8)-like operation for set the password for TCP MD5 Signature.
   61:  * Could be called with SABD_ADD or SADB_DELETE argument. Note that SADB_ADD
   62:  * argument is internally processed as a pair of SADB_ADD and SADB_DELETE
   63:  * operations to implement replace.
   64:  */
   65: static int
   66: setkey_md5(sockaddr *src, sockaddr *dst, char *passwd, uint type)
   67: {
   68:   uint passwd_len = passwd ? strlen(passwd) : 0;
   69: 
   70:   uint total =
   71:     sizeof(struct sadb_msg) +
   72:     sizeof(struct sadb_key) + PFKEY_ALIGN8(passwd_len) +
   73:     sizeof(struct sadb_sa) +
   74:     sizeof(struct sadb_x_sa2) +
   75:     sizeof(struct sadb_address) + PFKEY_ALIGN8(src->sa.sa_len) +
   76:     sizeof(struct sadb_address) + PFKEY_ALIGN8(dst->sa.sa_len);
   77: 
   78:   char *buf = alloca(total);
   79:   char *pos = buf;
   80:   uint len;
   81: 
   82:   memset(buf, 0, total);
   83: 
   84:   struct sadb_msg *msg = (void *) pos;
   85:   len = sizeof(struct sadb_msg);
   86:   msg->sadb_msg_version = PF_KEY_V2;
   87:   msg->sadb_msg_type = type;
   88:   msg->sadb_msg_satype = SADB_X_SATYPE_TCPSIGNATURE;
   89:   msg->sadb_msg_len = 0;	/* Fix it later */
   90:   msg->sadb_msg_pid = getpid();
   91:   pos += len;
   92: 
   93:   /* Set authentication algorithm and password */
   94:   struct sadb_key *key = (void *) pos;
   95:   len = sizeof(struct sadb_key) + PFKEY_ALIGN8(passwd_len);
   96:   key->sadb_key_len = PFKEY_UNIT64(len);
   97:   key->sadb_key_exttype = SADB_EXT_KEY_AUTH;
   98:   key->sadb_key_bits = passwd_len * 8;
   99:   memcpy(pos + sizeof(struct sadb_key), passwd, passwd_len);
  100:   pos += len;
  101: 
  102:   struct sadb_sa *sa = (void *) pos;
  103:   len = sizeof(struct sadb_sa);
  104:   sa->sadb_sa_len = PFKEY_UNIT64(len);
  105:   sa->sadb_sa_exttype = SADB_EXT_SA;
  106:   sa->sadb_sa_spi = htonl((u32) TCP_SIG_SPI);
  107:   sa->sadb_sa_auth = SADB_X_AALG_TCP_MD5;
  108:   sa->sadb_sa_encrypt = SADB_EALG_NONE;
  109:   sa->sadb_sa_flags = SADB_X_EXT_CYCSEQ;
  110:   pos += len;
  111: 
  112:   struct sadb_x_sa2 *sa2 = (void *) pos;
  113:   len = sizeof(struct sadb_x_sa2);
  114:   sa2->sadb_x_sa2_len = PFKEY_UNIT64(len);
  115:   sa2->sadb_x_sa2_exttype = SADB_X_EXT_SA2;
  116:   sa2->sadb_x_sa2_mode = IPSEC_MODE_ANY;
  117:   pos += len;
  118: 
  119:   /* Set source address */
  120:   struct sadb_address *saddr = (void *) pos;
  121:   len = sizeof(struct sadb_address) + PFKEY_ALIGN8(src->sa.sa_len);
  122:   saddr->sadb_address_len = PFKEY_UNIT64(len);
  123:   saddr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
  124:   saddr->sadb_address_proto = IPSEC_ULPROTO_ANY;
  125:   saddr->sadb_address_prefixlen = MAX_PREFIX_LENGTH;
  126:   memcpy(pos + sizeof(struct sadb_address), &src->sa, src->sa.sa_len);
  127:   pos += len;
  128: 
  129:   /* Set destination address */
  130:   struct sadb_address *daddr = (void *) pos;
  131:   len = sizeof(struct sadb_address) + PFKEY_ALIGN8(dst->sa.sa_len);
  132:   daddr->sadb_address_len = PFKEY_UNIT64(len);
  133:   daddr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
  134:   daddr->sadb_address_proto = IPSEC_ULPROTO_ANY;
  135:   daddr->sadb_address_prefixlen = MAX_PREFIX_LENGTH;
  136:   memcpy(pos + sizeof(struct sadb_address), &dst->sa, dst->sa.sa_len);
  137:   pos += len;
  138: 
  139:   len = pos - buf;
  140:   msg->sadb_msg_len = PFKEY_UNIT64(len);
  141: 
  142:   return setkey_send(msg, len);
  143: }
  144: 
  145: /*
  146:  * Manipulation with the IPsec SA/SP database
  147:  */
  148: static int
  149: sk_set_md5_in_sasp_db(sock *s, ip_addr local, ip_addr remote, struct iface *ifa, char *passwd)
  150: {
  151:   sockaddr src, dst;
  152:   sockaddr_fill(&src, s->af, local, ifa, 0);
  153:   sockaddr_fill(&dst, s->af, remote, ifa, 0);
  154: 
  155:   if (passwd && *passwd)
  156:   {
  157:     int len = strlen(passwd);
  158:     if (len > TCP_KEYLEN_MAX)
  159:       ERR_MSG("The password for TCP MD5 Signature is too long");
  160: 
  161:     if ((setkey_md5(&src, &dst, passwd, SADB_ADD) < 0) ||
  162: 	(setkey_md5(&dst, &src, passwd, SADB_ADD) < 0))
  163:       ERR_MSG("Cannot add TCP-MD5 password into the IPsec SA/SP database");
  164:   }
  165:   else
  166:   {
  167:     if ((setkey_md5(&src, &dst, NULL, SADB_DELETE) < 0) ||
  168: 	(setkey_md5(&dst, &src, NULL, SADB_DELETE) < 0))
  169:       ERR_MSG("Cannot delete TCP-MD5 password from the IPsec SA/SP database");
  170:   }
  171:   return 0;
  172: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>