Annotation of embedaddon/bird/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 "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: ERR_MSG("Cannot add TCP-MD5 password into the IPsec SA/SP database");
! 163: }
! 164: else
! 165: {
! 166: if (setkey_md5(&src, &dst, NULL, SADB_DELETE) < 0)
! 167: ERR_MSG("Cannot delete TCP-MD5 password from the IPsec SA/SP database");
! 168: }
! 169: return 0;
! 170: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>