Annotation of embedaddon/bird2/sysdep/bsd/setkey.h, revision 1.1

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 "sysdep/unix/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, uint pxlen, 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 = pxlen;
        !           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 = pxlen;
        !           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:   uint pxlen = (s->af == AF_INET) ? IP4_MAX_PREFIX_LENGTH : IP6_MAX_PREFIX_LENGTH;
        !           156: 
        !           157:   if (passwd && *passwd)
        !           158:   {
        !           159:     int len = strlen(passwd);
        !           160:     if (len > TCP_KEYLEN_MAX)
        !           161:       ERR_MSG("The password for TCP MD5 Signature is too long");
        !           162: 
        !           163:     if ((setkey_md5(&src, &dst, pxlen, passwd, SADB_ADD) < 0) ||
        !           164:        (setkey_md5(&dst, &src, pxlen, passwd, SADB_ADD) < 0))
        !           165:       ERR_MSG("Cannot add TCP-MD5 password into the IPsec SA/SP database");
        !           166:   }
        !           167:   else
        !           168:   {
        !           169:     if ((setkey_md5(&src, &dst, pxlen, NULL, SADB_DELETE) < 0) ||
        !           170:        (setkey_md5(&dst, &src, pxlen, NULL, SADB_DELETE) < 0))
        !           171:       ERR_MSG("Cannot delete TCP-MD5 password from the IPsec SA/SP database");
        !           172:   }
        !           173:   return 0;
        !           174: }

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