1*f2c2b5e4Spatrick /* $OpenBSD: vendor.c,v 1.6 2017/11/08 13:33:49 patrick Exp $ */
217f91f1cShshoexer /*
317f91f1cShshoexer * Copyright (c) 2006 Hans-Joerg Hoexer <hshoexer@openbsd.org>
417f91f1cShshoexer *
517f91f1cShshoexer * Permission to use, copy, modify, and distribute this software for any
617f91f1cShshoexer * purpose with or without fee is hereby granted, provided that the above
717f91f1cShshoexer * copyright notice and this permission notice appear in all copies.
817f91f1cShshoexer *
917f91f1cShshoexer * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1017f91f1cShshoexer * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1117f91f1cShshoexer * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1217f91f1cShshoexer * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1317f91f1cShshoexer * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1417f91f1cShshoexer * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1517f91f1cShshoexer * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1617f91f1cShshoexer */
1717f91f1cShshoexer
1817f91f1cShshoexer #include <sys/types.h>
1917f91f1cShshoexer #include <stdlib.h>
2017f91f1cShshoexer #include <string.h>
2117f91f1cShshoexer
2217f91f1cShshoexer #include "exchange.h"
2317f91f1cShshoexer #include "hash.h"
2417f91f1cShshoexer #include "log.h"
2517f91f1cShshoexer #include "message.h"
2617f91f1cShshoexer #include "vendor.h"
2717f91f1cShshoexer
2817f91f1cShshoexer static struct vendor_cap openbsd_vendor_cap[] = {
29*f2c2b5e4Spatrick { "OpenBSD-6.3", NULL, 0 },
3017f91f1cShshoexer };
3117f91f1cShshoexer
3217f91f1cShshoexer #define NUMVIDS (sizeof openbsd_vendor_cap / sizeof openbsd_vendor_cap[0])
3317f91f1cShshoexer
3417f91f1cShshoexer static int
setup_vendor_hashes(void)3517f91f1cShshoexer setup_vendor_hashes(void)
3617f91f1cShshoexer {
3717f91f1cShshoexer struct hash *hash;
3817f91f1cShshoexer int i, n = NUMVIDS;
3917f91f1cShshoexer
4017f91f1cShshoexer hash = hash_get(HASH_MD5);
4117f91f1cShshoexer if (!hash) {
4217f91f1cShshoexer log_print("setup_vendor_hashes: could not find MD5 hash");
43151ead9aSho return -1;
4417f91f1cShshoexer }
4517f91f1cShshoexer
4617f91f1cShshoexer for (i = 0; i < n; i++) {
4717f91f1cShshoexer openbsd_vendor_cap[i].hashsize = hash->hashsize;
4817f91f1cShshoexer openbsd_vendor_cap[i].hash = calloc(hash->hashsize,
4917f91f1cShshoexer sizeof(u_int8_t));
5017f91f1cShshoexer if (openbsd_vendor_cap[i].hash == NULL) {
5117f91f1cShshoexer log_error("setup_vendor_hashes: calloc failed");
5217f91f1cShshoexer goto errout;
5317f91f1cShshoexer }
5417f91f1cShshoexer
5517f91f1cShshoexer hash->Init(hash->ctx);
5617f91f1cShshoexer hash->Update(hash->ctx,
5717f91f1cShshoexer (unsigned char *)openbsd_vendor_cap[i].text,
5817f91f1cShshoexer strlen(openbsd_vendor_cap[i].text));
5917f91f1cShshoexer hash->Final(openbsd_vendor_cap[i].hash, hash->ctx);
6017f91f1cShshoexer
6117f91f1cShshoexer LOG_DBG((LOG_EXCHANGE, 50, "setup_vendor_hashes: "
6217f91f1cShshoexer "MD5(\"%s\") (%lu bytes)", openbsd_vendor_cap[i].text,
6317f91f1cShshoexer (unsigned long)hash->hashsize));
6417f91f1cShshoexer LOG_DBG_BUF((LOG_EXCHANGE, 50, "setup_vendor_hashes",
6517f91f1cShshoexer openbsd_vendor_cap[i].hash, hash->hashsize));
6617f91f1cShshoexer }
67151ead9aSho return 0;
6817f91f1cShshoexer
6917f91f1cShshoexer errout:
7017f91f1cShshoexer for (i = 0; i < n; i++)
7117f91f1cShshoexer free(openbsd_vendor_cap[i].hash);
72151ead9aSho return -1;
7317f91f1cShshoexer }
7417f91f1cShshoexer
7517f91f1cShshoexer void
vendor_init(void)7617f91f1cShshoexer vendor_init(void)
7717f91f1cShshoexer {
7817f91f1cShshoexer setup_vendor_hashes();
7917f91f1cShshoexer }
8017f91f1cShshoexer
8117f91f1cShshoexer int
add_vendor_openbsd(struct message * msg)8217f91f1cShshoexer add_vendor_openbsd(struct message *msg)
8317f91f1cShshoexer {
8417f91f1cShshoexer u_int8_t *buf;
8517f91f1cShshoexer size_t buflen;
8617f91f1cShshoexer int i, n = NUMVIDS;
8717f91f1cShshoexer
8817f91f1cShshoexer for (i = 0; i < n; i++) {
8917f91f1cShshoexer buflen = openbsd_vendor_cap[i].hashsize + ISAKMP_GEN_SZ;
9017f91f1cShshoexer if ((buf = calloc(buflen, sizeof(char))) == NULL) {
9117f91f1cShshoexer log_error("add_vendor_payload: calloc(%lu) failed",
9217f91f1cShshoexer (unsigned long)buflen);
93151ead9aSho return -1;
9417f91f1cShshoexer }
9517f91f1cShshoexer
9617f91f1cShshoexer SET_ISAKMP_GEN_LENGTH(buf, buflen);
9717f91f1cShshoexer memcpy(buf + ISAKMP_VENDOR_ID_OFF, openbsd_vendor_cap[i].hash,
9817f91f1cShshoexer openbsd_vendor_cap[i].hashsize);
9917f91f1cShshoexer if (message_add_payload(msg, ISAKMP_PAYLOAD_VENDOR, buf,
10017f91f1cShshoexer buflen, 1)) {
10117f91f1cShshoexer free(buf);
102151ead9aSho return -1;
10317f91f1cShshoexer }
10417f91f1cShshoexer }
10517f91f1cShshoexer
106151ead9aSho return 0;
10717f91f1cShshoexer }
10817f91f1cShshoexer
10917f91f1cShshoexer void
check_vendor_openbsd(struct message * msg,struct payload * p)11017f91f1cShshoexer check_vendor_openbsd(struct message *msg, struct payload *p)
11117f91f1cShshoexer {
11217f91f1cShshoexer u_int8_t *pbuf = p->p;
11317f91f1cShshoexer ssize_t vlen;
11417f91f1cShshoexer int i, n = NUMVIDS;
11517f91f1cShshoexer
11617f91f1cShshoexer if (msg->exchange->flags & EXCHANGE_FLAG_OPENBSD) {
11717f91f1cShshoexer p->flags |= PL_MARK;
11817f91f1cShshoexer return;
11917f91f1cShshoexer }
12017f91f1cShshoexer
12117f91f1cShshoexer vlen = GET_ISAKMP_GEN_LENGTH(pbuf) - ISAKMP_GEN_SZ;
12217f91f1cShshoexer
12317f91f1cShshoexer for (i = 0; i < n; i++) {
12417f91f1cShshoexer if (vlen != openbsd_vendor_cap[i].hashsize) {
12517f91f1cShshoexer LOG_DBG((LOG_EXCHANGE, 90,
12617f91f1cShshoexer "check_vendor_openbsd: bad size %lu != %lu",
12717f91f1cShshoexer (unsigned long)vlen,
12817f91f1cShshoexer (unsigned long)openbsd_vendor_cap[i].hashsize));
12917f91f1cShshoexer continue;
13017f91f1cShshoexer }
13117f91f1cShshoexer if (memcmp(openbsd_vendor_cap[i].hash, pbuf + ISAKMP_GEN_SZ,
13217f91f1cShshoexer vlen) == 0) {
13317f91f1cShshoexer msg->exchange->flags |= EXCHANGE_FLAG_OPENBSD;
13417f91f1cShshoexer LOG_DBG((LOG_EXCHANGE, 10, "check_vendor_openbsd: "
13517f91f1cShshoexer "OpenBSD (%s)", openbsd_vendor_cap[i].text));
13617f91f1cShshoexer }
13717f91f1cShshoexer p->flags |= PL_MARK;
13817f91f1cShshoexer }
13917f91f1cShshoexer }
140