⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 klips.c

📁 This isakmpd, a BSD-licensed ISAKMP/Oakley (a.k.a. IKE) implementation.
💻 C
📖 第 1 页 / 共 2 页
字号:
/*	$OpenBSD: klips.c,v 1.3 2003/09/26 15:59:34 aaron Exp $	*//* * Copyright (c) 1999 Niklas Hallqvist.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *//* * This code was written under funding by Ericsson Radio Systems. */#include <asm/types.h>#include <sys/types.h>#include <sys/ioctl.h>#include <sys/stat.h>#include <sys/socket.h>#include <linux/sockios.h>#include <net/route.h>#include <netinet/in.h>#include <arpa/inet.h>#include <errno.h>#include <fcntl.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <unistd.h>#include <freeswan.h>#include <net/ipsec/radij.h>#include <net/ipsec/ipsec_encap.h>#include <net/ipsec/ipsec_netlink.h>#include <net/ipsec/ipsec_xform.h>#include <net/ipsec/ipsec_ipe4.h>#include <net/ipsec/ipsec_ah.h>#include <net/ipsec/ipsec_esp.h>#include "sysdep.h"#include "conf.h"#include "exchange.h"#include "hash.h"#include "ipsec.h"#include "ipsec_doi.h"#include "ipsec_num.h"#include "isakmp.h"#include "log.h"#include "klips.h"#include "sa.h"#include "timer.h"#include "transport.h"#define KLIPS_DEVICE "/dev/ipsec"#define PROC_ROUTE_FILE	"/proc/net/route"#define PROC_ROUTE_FMT	"%15s %127s %127s %X %d %d %d %127s %d %d %d\n"/* XXX Maybe these are available through some system-supplied define?  */#define AH_NEW_XENCAP_LEN (3 * sizeof(u_short) + 2 * sizeof(u_char))#define ESP_NEW_XENCAP_LEN sizeof (struct espblkrply_edata)#define EMT_GRPSPIS_COMPLEN (sizeof (((struct encap_msghdr *)0)->em_rel[0]))/* How often should we check that connections we require to be up, are up?  */#define KLIPS_CHECK_FREQ 60static int klips_socket;/* Open the KLIPS device.  */intklips_open (){  int fd;  fd = open (KLIPS_DEVICE, O_RDWR);  if (fd == -1)    {      log_error ("klips_open: open (\"%s\", O_RDWR) failed", KLIPS_DEVICE);      return -1;    }  klips_socket = fd;  return fd;}/* Write a KLIPS request down to the kernel.  */static intklips_write (struct encap_msghdr *em){  ssize_t n;  em->em_magic = EM_MAGIC;  em->em_version = 0;  LOG_DBG_BUF ((LOG_SYSDEP, 30, "klips_write: em", (u_int8_t *)em,		em->em_msglen));  n = write (klips_socket, em, em->em_msglen);  if (n == -1)    {      log_error ("write (%d, ...) failed", klips_socket);      return -1;    }  if ((size_t)n != em->em_msglen)    {      log_error ("write (%d, ...) returned prematurely", klips_socket);      return -1;    }  return 0;}/* * Generate a SPI for protocol PROTO and the source/destination pair given by * SRC, SRCLEN, DST & DSTLEN.  Stash the SPI size in SZ. */u_int8_t *klips_get_spi (size_t *sz, u_int8_t proto, struct sockaddr *src,	       struct sockaddr *dst, u_int32_t seq){  u_int8_t *spi;  u_int32_t spinum;  *sz = IPSEC_SPI_SIZE;  spi = malloc (*sz);  if (!spi)    return 0;  do    spinum = sysdep_random ();  while (spinum < IPSEC_SPI_LOW);  spinum = htonl (spinum);  memcpy (spi, &spinum, *sz);  LOG_DBG_BUF ((LOG_SYSDEP, 50, "klips_get_spi: spi", spi, *sz));  return spi;}/* Group 2 SPIs in a chain.  XXX Not fully implemented yet.  */intklips_group_spis (struct sa *sa, struct proto *proto1, struct proto *proto2,		  int incoming){  struct encap_msghdr *emsg = 0;  struct sockaddr *dst;  emsg = calloc (1, EMT_GRPSPIS_FLEN + 2 * EMT_GRPSPIS_COMPLEN);  if (!emsg)    return -1;  emsg->em_msglen = EMT_GRPSPIS_FLEN + 2 * EMT_GRPSPIS_COMPLEN;  emsg->em_type = EMT_GRPSPIS;  /*   * XXX The code below is wrong if we are in tunnel mode.   * The fix is to reorder stuff so the IP-in-IP SA will always come   * upfront, and if there are two such, one is dropped.   */  memcpy (&emsg->em_rel[0].emr_spi, proto1->spi[incoming],	  sizeof emsg->em_rel[0].emr_spi);  memcpy (&emsg->em_rel[1].emr_spi, proto2->spi[incoming],	  sizeof emsg->em_rel[1].emr_spi);  if (incoming)    sa->transport->vtbl->get_src (sa->transport, &dst);  else    sa->transport->vtbl->get_dst (sa->transport, &dst);  emsg->em_rel[0].emr_dst    = emsg->em_rel[1].emr_dst = ((struct sockaddr_in *)dst)->sin_addr;  /* XXX What if IPCOMP etc. comes along?  */  emsg->em_rel[0].emr_proto    = proto1->proto == IPSEC_PROTO_IPSEC_ESP ? IPPROTO_ESP : IPPROTO_AH;  emsg->em_rel[1].emr_proto    = proto2->proto == IPSEC_PROTO_IPSEC_ESP ? IPPROTO_ESP : IPPROTO_AH;  if (klips_write (emsg))    goto cleanup;  free (emsg);  LOG_DBG ((LOG_SYSDEP, 50, "klips_group_spis: done"));  return 0; cleanup:  if (emsg)    free (emsg);  return -1;}/* Store/update a SPI with full information into the kernel.  */intklips_set_spi (struct sa *sa, struct proto *proto, int incoming,	       struct sa *isakmp_sa){  struct encap_msghdr *emsg = 0;  struct ipsec_proto *iproto = proto->data;  struct sockaddr *dst, *src;  int keylen, hashlen;  size_t len;  struct ipe4_xdata *ip4x;  /* Actually works for all.  */  struct espblkrply_edata *edx;  /* Actually works for all.  */  struct ahhmacmd5_edata *amx;  switch (proto->proto)    {    case IPSEC_PROTO_IPSEC_ESP:      keylen = ipsec_esp_enckeylength (proto);      hashlen = ipsec_esp_authkeylength (proto);      len = EMT_SETSPI_FLEN + ESP_NEW_XENCAP_LEN;      emsg = calloc (1, len);      if (!emsg)	return -1;      emsg->em_proto = IPPROTO_ESP;      edx = (struct espblkrply_edata *)emsg->em_dat;      /* Funny expression due to I just want one switch.  */      switch (proto->id | (iproto->auth << 8))	{	case IPSEC_ESP_3DES:	  emsg->em_alg = XF_ESP3DES;	  break;	case IPSEC_ESP_3DES | (IPSEC_AUTH_HMAC_MD5 << 8):	  emsg->em_alg = XF_ESP3DESMD596;	  break;	case IPSEC_ESP_3DES | (IPSEC_AUTH_HMAC_SHA << 8):	  emsg->em_alg = XF_ESP3DESSHA196;	  break;	default:	  LOG_DBG ((LOG_SYSDEP, 10,		    "klips_set_spi: Unsupported enc/auth alg negotiated"));	  return -1;	}      /* XXX What if we have a protocol requiring IV?  */      edx->eme_ivlen = EMT_ESPDES_IV_SZ;      edx->eme_klen = keylen;      edx->ame_klen = hashlen;#if 0      /* I have reason to believe Shared-SADB won't work at all in KLIPS.  */      edx->eme_ooowin	= conf_get_str ("General", "Shared-SADB") ? 0 : iproto->replay_window;#else      edx->eme_ooowin = iproto->replay_window;#endif      /*       * XXX Pluto sets the unused by KLIPS flag EME_INITIATOR in       * edx->eme_flags, if the party is the initiator.  Should we too?       */      edx->eme_flags = 0;      memcpy (edx->eme_key, iproto->keymat[incoming], keylen);      if (iproto->auth)	memcpy (edx->ame_key, iproto->keymat[incoming] + keylen, hashlen);      break;    case IPSEC_PROTO_IPSEC_AH:      hashlen = ipsec_ah_keylength (proto);      len = EMT_SETSPI_FLEN + AH_NEW_XENCAP_LEN + hashlen;      emsg = calloc (1, len);      if (!emsg)	return -1;      emsg->em_proto = IPPROTO_AH;      amx = (struct ahhmacmd5_edata *)emsg->em_dat;      switch (proto->id)	{	case IPSEC_AH_MD5:	  emsg->em_alg = XF_AHHMACMD5;	  break;	case IPSEC_AH_SHA:	  emsg->em_alg = XF_AHHMACSHA1;	  break;	default:	  /* XXX Log?  */	  goto cleanup;	}      /* XXX Should we be able to send in different lengths here?  */      amx->ame_alen = amx->ame_klen = hashlen;#if 0      /* I have reason to believe Shared-SADB won't work at all in KLIPS.  */      amx->ame_ooowin	= conf_get_str ("General", "Shared-SADB") ? 0 : iproto->replay_window;#else      amx->ame_ooowin = iproto->replay_window;#endif      amx->ame_replayp = amx->ame_ooowin > 0;      memcpy (amx->ame_key, iproto->keymat[incoming], hashlen);      break;    default:      /* XXX Log?  */      goto cleanup;    }  emsg->em_msglen = len;  emsg->em_type = EMT_SETSPI;  memcpy (&emsg->em_spi, proto->spi[incoming], sizeof emsg->em_spi);  emsg->em_flags = incoming ? EMT_INBOUND : 0;  /*   * XXX Addresses has to be thought through.  Assumes IPv4.   */  sa->transport->vtbl->get_dst (sa->transport, &dst);  sa->transport->vtbl->get_src (sa->transport, &src);  emsg->em_dst

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -