Annotation of embedaddon/bird/sysdep/bsd/setkey.h, revision 1.1.1.2

1.1       misho       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: 
1.1.1.2 ! misho     161:     if ((setkey_md5(&src, &dst, passwd, SADB_ADD) < 0) ||
        !           162:        (setkey_md5(&dst, &src, passwd, SADB_ADD) < 0))
1.1       misho     163:       ERR_MSG("Cannot add TCP-MD5 password into the IPsec SA/SP database");
                    164:   }
                    165:   else
                    166:   {
1.1.1.2 ! misho     167:     if ((setkey_md5(&src, &dst, NULL, SADB_DELETE) < 0) ||
        !           168:        (setkey_md5(&dst, &src, NULL, SADB_DELETE) < 0))
1.1       misho     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>