Import ipsec-tools (tag ipsec-tools-0_6-base in ipsec-tools CVS)

ipsec-tools is a fork from KAME racoon/libipsec/setkey, with many
enhancements.
This commit is contained in:
manu 2005-02-12 11:11:11 +00:00
parent ef3f4c0f7e
commit a8f0ad3c37
222 changed files with 88211 additions and 0 deletions

16
crypto/dist/ipsec-tools/.cvsignore vendored Normal file
View File

@ -0,0 +1,16 @@
Makefile
Makefile.in
aclocal.m4
autom4te*
config.*
configure
depcomp
install-sh
ltmain.sh
libtool
missing
ylwrap
mkinstalldirs
stamp-h*
*.tar.gz
package_version.h

1470
crypto/dist/ipsec-tools/ChangeLog vendored Normal file

File diff suppressed because it is too large Load Diff

3
crypto/dist/ipsec-tools/Makefile.am vendored Normal file
View File

@ -0,0 +1,3 @@
SUBDIRS = src @RPM@
EXTRA_DIST = bootstrap README NEWS depcomp

99
crypto/dist/ipsec-tools/NEWS vendored Normal file
View File

@ -0,0 +1,99 @@
Version history:
----------------
0.6??? - ??
o PAM support for Xauth
o Privilege separation
o ESP fragmentation in tunnel mode can be tunned (NetBSD only)
o racoon admin interface is exported (header and library) to
help building control programs for racoon (think GUI)
0.5??? - ??
o Rewritten buildsystem. Now completely autoconfed, automaked,
libtoolized.
o IPsec-tools now compiles on NetBSD and FreeBSD again.
o Support for server-side hybrid authentication, with full
RADIUS supoort. This is interoperable with the Cisco VPN client.
o Support for client-side hybrid authentication (Tested only with
a racoon server)
o ISAKMP mode config support
o IKE fragmentation support
o Fixed FWD policy support.
o Fixed IPv6 compilation.
o Readline is optional, fixed setkey when compiled without readline.
o Configurable Root-CA certificate.
o Dead Peer Detection (DPD) support.
0.4rc1 - 09 August 2004
o Merged support for PlainRSA keys from the 'plainrsa' branch.
o Inheritance of 'remote{}' sections.
o Support for SPD policy priorities in setkey.
o Ciphers are now used through the 'EVP' interface which allows
using hardware crypto accelerators.
o Setkey has new option -n (no action).
o All source files now have 3-clause BSD license.
0.3 - 14 April 2004
o Fixed setkey to handle multiline commands again.
o Added command 'exit' to setkey.
o Fixed racoon to only Warn if no CRL was found.
o Improved testsuite.
0.3rc5 - 05 April 2004
o Security bugfix WRT handling X.509 signatures.
o Stability fix WRT unknown PF_KEY messages.
o Fixed NAT-T with more proposals (e.g. more crypto algos).
o Setkey parses lines one by one => doesn't exit on errors.
o Setkey supports readline => more user friendly.
0.3rc4 - 25 March 2004
o Fixed adding "null" encryption via 'setkey'.
o Fixed segfault when using AES in Phase1 with OpenSSL>=0.9.7
o Fixed NAT-T in aggresive mode.
o Fixed testsuite and added testsuite run into make check.
0.3rc3 - 19 March 2004
o Fixed compilation error with --enble-yydebug
o Better diagnostic when proposals don't match.
o Changed/added options to setkey.
0.3rc2 - 11 March 2004
o Added documentation for NAT-T
o Better NAT-T diagnostic.
o Test and workaround for missing va_copy()
0.3rc1 - 04 March 2004
o Support for NAT Traversal (NAT-T)
0.2.4 - 29 January 2004
o Sync with KAME as of 2004-01-07
o Fixed unauthorized deletion of SA in racoon (again).
0.2.3 - 15 January 2004
o Support for SA lifetime specified in bytes
(see setkey -bs/-bh options)
o Enhance support for OpenSSL 0.9.7
o Let racoon be more verbose
o Fixed some simple bugs (see ChangeLog for details)
o Fixed unauthorized deletion of SA in racoon
o Fixed problems on AMD64
o Ignore multicast addresses for IKE
0.2.2 - 13 March 2003
o Fix racoon to build on some systems that require linking against -lfl
o add an RPM spec to the distribution
0.2.1 - 07 March 2003
o Fix some more gcc-3.2.2 compiler warnings
o Fix racoon to actually configure with ssl in a non-standard location
o Fix racoon to not complain if krb5-config is not installed
0.2 - 06 March 2003
o Glibc-2.3 support
o OpenSSL-0.9.7 support
o Fixed duplicate-macro problems
o Fix racoon lex/yacc support
o Install psk.txt mode 600, racoon.conf mode 644
o Fix racoon to look in the correct directory for config files
0.1 - 03 March 2003
o Initial release of IPsec-Tools

31
crypto/dist/ipsec-tools/README vendored Normal file
View File

@ -0,0 +1,31 @@
IPsec-tools
===========
This package provides a way to use the native IPsec functionality
in the Linux 2.6+ kernel. It works as well on NetBSD and FreeBSD.
- libipsec, a PF_KEYv2 library
- setkey, a tool to directly manipulate policies and SAs
- racoon, an IKEv1 keying daemon
IPsec-tools were ported to Linux from the KAME project
(http://www.kame.net) by Derek Atkins <derek@ihtfp.com>.
Currently the package is actively maintained and developed
by Michal Ludvig <mludvig@suse.cz>, Aidas Kasparas <a.kasparas@gmc.lt>
and Emmanuel Dreyfus <manu@netbsd.org>.
Sources can be found at the IPsec-Tools home page at:
http://ipsec-tools.sourceforge.net/
Please report any problems to the mailing list:
ipsec-tools-devel@lists.sourceforge.net
(it is called 'devel' but feel free to send general
questions there as well :-)
You can also browse the list archive:
http://sourceforge.net/mailarchive/forum.php?forum_id=32000
Credits:
IHTFP Consulting, see http://www.ihtfp.com/
SUSE Linux AG, see http://www.suse.com/

193
crypto/dist/ipsec-tools/acracoon.m4 vendored Normal file
View File

@ -0,0 +1,193 @@
dnl RACOON_PATH_LIBS(FUNCTION, LIB, SEARCH-PATHS [, ACTION-IF-FOUND
dnl [, ACTION-IF-NOT-FOUND [, OTHER-LIBRARIES]]])
dnl Search for a library defining FUNC, if it's not already available.
AC_DEFUN([RACOON_PATH_LIBS],
[AC_PREREQ([2.13])
AC_CACHE_CHECK([for $2 containing $1], [ac_cv_search_$1],
[ac_func_search_save_LIBS="$LIBS"
ac_cv_search_$1="no"
AC_TRY_LINK_FUNC([$1], [ac_cv_search_$1="none required"],
[LIBS="-l$2 $LIBS"
AC_TRY_LINK_FUNC([$1], [ac_cv_search_$1="-l$2"], [])])
LIBS="$ac_func_search_save_LIBS"
ifelse("x$3", "x", , [ test "$ac_cv_search_$1" = "no" && for i in $3; do
LIBS="-L$i -l$2 $ac_func_search_save_LIBS"
AC_TRY_LINK_FUNC([$1],
[ac_cv_search_$1="-L$i -l$2"
break])
done
LIBS="$ac_func_search_save_LIBS" ]) ])
if test "$ac_cv_search_$1" != "no"; then
test "$ac_cv_search_$1" = "none required" || LIBS="$ac_cv_search_$1 $LIBS"
$4
else :
$5
fi])
dnl Check if either va_copy() or __va_copy() is available. On linux systems
dnl at least one of these should be present.
AC_DEFUN([RACOON_CHECK_VA_COPY], [
saved_CFLAGS=$CFLAGS
CFLAGS="-Wall -O2"
AC_CACHE_CHECK([for an implementation of va_copy()],
ac_cv_va_copy,[
AC_TRY_RUN([#include <stdarg.h>
void func (int i, ...) {
va_list args1, args2;
va_start (args1, i);
va_copy (args2, args1);
if (va_arg (args1, int) != 1 || va_arg (args2, int) != 1)
exit (1);
va_end (args1);
va_end (args2);
}
int main() {
func (0, 1);
return 0;
}],
[ac_cv_va_copy=yes],
[ac_cv_va_copy=no],
[])
])
if test x$ac_cv_va_copy != xyes; then
AC_CACHE_CHECK([for an implementation of __va_copy()],
ac_cv___va_copy,[
AC_TRY_RUN([#include <stdarg.h>
void func (int i, ...) {
va_list args1, args2;
va_start (args1, i);
__va_copy (args2, args1);
if (va_arg (args1, int) != 1 || va_arg (args2, int) != 1)
exit (1);
va_end (args1);
va_end (args2);
}
int main() {
func (0, 1);
return 0;
}],
[ac_cv___va_copy=yes],
[ac_cv___va_copy=no],
[])
])
fi
if test "x$ac_cv_va_copy" = "xyes"; then
va_copy_func=va_copy
elif test "x$ac_cv___va_copy" = "xyes"; then
va_copy_func=__va_copy
fi
if test -n "$va_copy_func"; then
AC_DEFINE_UNQUOTED(VA_COPY,$va_copy_func,
[A 'va_copy' style function])
else
AC_MSG_WARN([Hmm, neither va_copy() nor __va_copy() found.])
AC_MSG_WARN([Using a generic fallback.])
fi
CFLAGS=$saved_CFLAGS
unset saved_CFLAGS
])
AC_DEFUN([RACOON_CHECK_BUGGY_GETADDRINFO], [
AC_MSG_CHECKING(getaddrinfo bug)
saved_CFLAGS=$CFLAGS
CFLAGS="-Wall -O2"
AC_TRY_RUN([
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
int main()
{
int passive, gaierr, inet4 = 0, inet6 = 0;
struct addrinfo hints, *ai, *aitop;
char straddr[INET6_ADDRSTRLEN], strport[16];
for (passive = 0; passive <= 1; passive++) {
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_flags = passive ? AI_PASSIVE : 0;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_socktype = SOCK_STREAM;
if ((gaierr = getaddrinfo(NULL, "54321", &hints, &aitop)) != 0) {
(void)gai_strerror(gaierr);
goto bad;
}
for (ai = aitop; ai; ai = ai->ai_next) {
if (ai->ai_addr == NULL ||
ai->ai_addrlen == 0 ||
getnameinfo(ai->ai_addr, ai->ai_addrlen,
straddr, sizeof(straddr), strport, sizeof(strport),
NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
goto bad;
}
switch (ai->ai_family) {
case AF_INET:
if (strcmp(strport, "54321") != 0) {
goto bad;
}
if (passive) {
if (strcmp(straddr, "0.0.0.0") != 0) {
goto bad;
}
} else {
if (strcmp(straddr, "127.0.0.1") != 0) {
goto bad;
}
}
inet4++;
break;
case AF_INET6:
if (strcmp(strport, "54321") != 0) {
goto bad;
}
if (passive) {
if (strcmp(straddr, "::") != 0) {
goto bad;
}
} else {
if (strcmp(straddr, "::1") != 0) {
goto bad;
}
}
inet6++;
break;
case AF_UNSPEC:
goto bad;
break;
default:
/* another family support? */
break;
}
}
}
if (!(inet4 == 0 || inet4 == 2))
goto bad;
if (!(inet6 == 0 || inet6 == 2))
goto bad;
if (aitop)
freeaddrinfo(aitop);
exit(0);
bad:
if (aitop)
freeaddrinfo(aitop);
exit(1);
}
],
AC_MSG_RESULT(good)
buggygetaddrinfo=no,
AC_MSG_RESULT(buggy)
buggygetaddrinfo=yes,
AC_MSG_RESULT(buggy)
buggygetaddrinfo=yes)
CFLAGS=$saved_CFLAGS
unset saved_CFLAGS
])

13
crypto/dist/ipsec-tools/bootstrap vendored Executable file
View File

@ -0,0 +1,13 @@
#!/bin/sh
set -x
# Remove autoconf 2.5x's cache directory
rm -rf autom4te*.cache
aclocal -I . || exit 1
autoheader || exit 1
libtoolize --force --copy || exit 1
automake --foreign --add-missing --copy || exit 1
autoconf || exit 1

562
crypto/dist/ipsec-tools/configure.ac vendored Normal file
View File

@ -0,0 +1,562 @@
dnl -*- mode: m4 -*-
dnl $Id: configure.ac,v 1.1.1.1 2005/02/12 11:11:16 manu Exp $
AC_PREREQ(2.52)
AC_INIT(ipsec-tools, 0.5pre)
AC_CONFIG_SRCDIR([configure.ac])
AM_CONFIG_HEADER(config.h)
AM_INIT_AUTOMAKE(dist-bzip2)
AC_ENABLE_SHARED(no)
AC_PROG_CC
AM_PROG_CC_STDC
AC_HEADER_STDC
AC_PROG_LIBTOOL
AC_PROG_YACC
AM_PROG_LEX
AC_SUBST(LEXLIB)
AC_PROG_EGREP
CFLAGS_ADD="$CFLAGS_ADD -Wall -Werror -Wno-unused"
case $host in
*netbsd*)
LDFLAGS="-Wl,-R/usr/pkg/lib $LDFLAGS"
;;
*linux*)
LIBS="$LIBS -lresolv"
INSTALL_OPTS="-o bin -g bin"
INCLUDE_GLIBC="include-glibc"
RPM="rpm"
AC_SUBST(INSTALL_OPTS)
AC_SUBST(INCLUDE_GLIBC)
AC_SUBST(RPM)
;;
esac
# Look up some IPsec-related headers
AC_CHECK_HEADER(net/pfkeyv2.h, [have_net_pfkey=yes], [have_net_pfkey=no])
AC_CHECK_HEADER(netinet/ipsec.h, [have_netinet_ipsec=yes], [have_netinet_ipsec=no])
AC_CHECK_HEADER(netinet6/ipsec.h, [have_netinet6_ipsec=yes], [have_netinet6_ipsec=no])
# NetBSD has <netinet6/ipsec.h> but not <netinet/ipsec.h>
if test "$have_netinet_ipsec$have_netinet6_ipsec" = noyes; then
have_netinet_ipsec=yes
AC_DEFINE(HAVE_NETINET6_IPSEC, [], [Use <netinet6/ipsec.h>])
fi
case "$host_os" in
*linux*)
AC_ARG_WITH(kernel-headers,
AC_HELP_STRING([--with-kernel-headers=/lib/modules/<uname>/build/include],
[where your Linux Kernel headers are installed]),
[ KERNEL_INCLUDE="$with_kernel_headers"
CONFIGURE_AMFLAGS="--with-kernel-headers=$with_kernel_headers"
AC_SUBST(CONFIGURE_AMFLAGS) ],
[ KERNEL_INCLUDE="/lib/modules/`uname -r`/build/include" ])
AC_CHECK_FILE($KERNEL_INCLUDE/linux/pfkeyv2.h, ,
[ AC_CHECK_FILE(/usr/src/linux/include/linux/pfkeyv2.h,
KERNEL_INCLUDE=/usr/src/linux/include ,
[ AC_MSG_ERROR([Unable to find linux-2.6 kernel headers. Aborting.]) ] ) ] )
AC_SUBST(KERNEL_INCLUDE)
# We need the configure script to run with correct kernel headers.
# However we don't want to point to kernel source tree in compile time,
# i.e. this will be removed from CPPFLAGS at the end of configure.
CPPFLAGS="-I$KERNEL_INCLUDE $CPPFLAGS"
AC_CHECK_MEMBER(struct sadb_x_policy.sadb_x_policy_priority,
[AC_DEFINE(HAVE_PFKEY_POLICY_PRIORITY, [],
[Are PF_KEY policy priorities supported?])], [],
[#include "$KERNEL_INCLUDE/linux/pfkeyv2.h"])
GLIBC_BUGS='-include ${top_srcdir}/src/include-glibc/glibc-bugs.h -I${top_srcdir}/src/include-glibc -I${top_builddir}/src/include-glibc'
AC_SUBST(GLIBC_BUGS)
GLIBC_BUGS_LOCAL="-include ${srcdir-.}/src/include-glibc/glibc-bugs.h -I${srcdir-.}/src/include-glibc -I./src/include-glibc"
CPPFLAGS="$GLIBC_BUGS_LOCAL $CPPFLAGS"
;;
*)
if test "$have_net_pfkey$have_netinet_ipsec" != yesyes; then
if test "$have_net_pfkey" = yes; then
AC_MSG_ERROR([Found net/pfkeyv2.h but not netinet/ipsec.h. Aborting.])
else
AC_MSG_ERROR([Found netinet/ipsec.h but not net/pfkeyv2.h. Aborting.])
fi
fi
;;
esac
### Some basic toolchain checks
# Checks for header files.
AC_HEADER_STDC
AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS(limits.h sys/time.h unistd.h stdarg.h varargs.h)
# Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_TYPE_PID_T
AC_TYPE_SIZE_T
AC_HEADER_TIME
AC_STRUCT_TM
# Checks for library functions.
AC_FUNC_MEMCMP
AC_TYPE_SIGNAL
AC_FUNC_VPRINTF
AC_CHECK_FUNCS(gettimeofday select socket strerror strtol strtoul strlcpy)
AC_REPLACE_FUNCS(strdup)
RACOON_CHECK_VA_COPY
# Check if printf accepts "%z" type modifier for size_t argument
AC_MSG_CHECKING(if printf accepts %z)
saved_CFLAGS=$CFLAGS
CFLAGS="$CFLAGS -Wall -Werror"
AC_TRY_COMPILE([
#include <stdio.h>
], [
printf("%zu\n", (size_t)-1);
],
[AC_MSG_RESULT(yes)],
[AC_MSG_RESULT(no); CFLAGS_ADD="$CFLAGS_ADD -Wno-format"])
CFLAGS=$saved_CFLAGS
# Can we use __func__ macro?
AC_MSG_CHECKING(if __func__ is available)
AC_TRY_COMPILE(
[#include <stdio.h>
], [char *x = __func__;],
[AC_DEFINE([HAVE_FUNC_MACRO], [], [Have __func__ macro])
AC_MSG_RESULT(yes)],
[AC_MSG_RESULT(no)])
# Check if readline support is requested
AC_MSG_CHECKING(if readline support is requested)
AC_ARG_WITH(readline,
[ --with-readline support readline input (yes by default)],
[with_readline="$withval"], [with_readline="yes"])
AC_MSG_RESULT($with_readline)
# Is readline available?
if test $with_readline != "no"; then
AC_CHECK_HEADER([readline/readline.h],
[AC_CHECK_LIB(readline, readline, [
AC_DEFINE(HAVE_READLINE, [],
[Is readline available?])
LIBS="$LIBS -lreadline"
], [])], [])
fi
# Check if a different OpenSSL directory was specified
AC_MSG_CHECKING(if --with-openssl option is specified)
AC_ARG_WITH(openssl, [ --with-openssl=DIR specify OpenSSL directory],
[crypto_dir=$withval])
AC_MSG_RESULT(${crypto_dir-default})
if test "x$crypto_dir" != "x"; then
LIBS="$LIBS -L${crypto_dir}/lib"
CPPFLAGS_ADD="-I${crypto_dir}/include $CPPFLAGS_ADD"
fi
AC_MSG_CHECKING(openssl version)
AC_EGREP_CPP(yes, [#include <openssl/opensslv.h>
#if OPENSSL_VERSION_NUMBER >= 0x0090602fL
yes
#endif], [AC_MSG_RESULT(ok)], [AC_MSG_RESULT(too old)
AC_MSG_ERROR([OpenSSL version must be 0.9.6 or higher. Aborting.])
])
AC_CHECK_HEADERS(openssl/engine.h)
# checking rijndael
AC_CHECK_HEADERS([openssl/aes.h], [],
[CRYPTOBJS="$CRYPTOBJS rijndael-api-fst.o rijndael-alg-fst.o"])
# checking sha2
AC_MSG_CHECKING(sha2 support)
AC_DEFINE([WITH_SHA2], [], [SHA2 support])
AC_CHECK_HEADER(openssl/sha2.h, [], [
CPPFLAGS_ADD="$CPPFLAGS_ADD -I./\${top_srcdir}/src/racoon/missing"
AC_LIBOBJ([sha2])
CRYPTOBJS="$CRYPTOBJS sha2.o"])
AC_SUBST(CRYPTOBJS)
# Option --enable-adminport
AC_MSG_CHECKING(if --enable-adminport option is specified)
AC_ARG_ENABLE(adminport,
[ --enable-adminport enable admin port],
[], [enable_adminport=no])
if test $enable_adminport = "yes"; then
AC_DEFINE([ENABLE_ADMINPORT], [], [Enable admin port])
fi
AC_MSG_RESULT($enable_adminport)
# Check for Kerberos5 support
AC_MSG_CHECKING(if --enable-gssapi option is specified)
AC_ARG_ENABLE(gssapi,
[ --enable-gssapi enable GSS-API authentication],
[], [enable_gssapi=no])
AC_MSG_RESULT($enable_gssapi)
AC_PATH_PROG(KRB5_CONFIG,krb5-config,no)
if test "x$enable_gssapi" = "xyes"; then
if test "$KRB5_CONFIG" != "no"; then
krb5_incdir="`$KRB5_CONFIG --cflags gssapi`"
krb5_libs="`$KRB5_CONFIG --libs gssapi`"
else
# No krb5-config; let's make some assumptions based on
# the OS.
case $host_os in
netbsd*)
krb5_incdir="-I/usr/include/krb5"
krb5_libs="-lgssapi -lkrb5 -lcom_err -lroken -lasn1"
;;
*)
AC_MSG_ERROR([krb5-config not found, but needed for GSSAPI support. Aborting.])
;;
esac
fi
LIBS="$LIBS $krb5_libs"
CPPFLAGS_ADD="$krb5_incdir $CPPFLAGS_ADD"
AC_DEFINE([HAVE_GSSAPI], [], [Enable GSS API])
fi
AC_MSG_CHECKING([if --enable-hybrid option is specified])
AC_ARG_ENABLE(hybrid,
[ --enable-hybrid enable hybrid, both mode-cfg and xauth support],
[
LIBS="$LIBS -lcrypt";
enable_hybrid=yes;
HYBRID_OBJS="isakmp_xauth.o isakmp_cfg.o isakmp_unity.o throttle.o"
AC_SUBST(HYBRID_OBJS)
AC_DEFINE([ENABLE_HYBRID], [], [Hybrid authentication support])
],
[enable_hybrid=no])
AC_MSG_RESULT($enable_hybrid)
AC_MSG_CHECKING([if --enable-frag option is specified])
AC_ARG_ENABLE(frag,
[ --enable-frag enable IKE fragmentation payload support],
[
LIBS="$LIBS -lcrypt";
enable_frag=yes;
FRAG_OBJS="isakmp_frag.o"
AC_SUBST(FRAG_OBJS)
AC_DEFINE([ENABLE_FRAG], [], [IKE fragmentation support])
],
[enable_frag=no])
AC_MSG_RESULT($enable_frag)
AC_MSG_CHECKING(if --with-libradius option is specified)
AC_ARG_WITH(libradius,
[ --with-libradius=DIR specify libradius path (like/usr/pkg)],
[libradius_dir=$withval],
[libradius_dir=no])
AC_MSG_RESULT($libradius_dir)
if test "$libradius_dir" != "no"; then
if test "$libradius_dir" = "yes" ; then
libradius_dir="";
fi;
if test "x$libradius_dir" = "x"; then
RACOON_PATH_LIBS(rad_create_request, lradius)
else
if test -d "$libradius_dir/lib" -a \
-d "$libradius_dir/include" ; then
RACOON_PATH_LIBS(rad_create_request, lradius, "$libradius_dir/lib")
CPPFLAGS_ADD="$CPPFLAGS_ADD -I$libradius_dir/include"
else
AC_MSG_ERROR([RADIUS libs or includes not found. Aborting.])
fi
fi
AC_DEFINE([HAVE_LIBRADIUS], [], [Hybrid authentication uses RADIUS])
LIBS="$LIBS -L$libradius_dir/lib -R$libradius_dir/lib -lradius"
AC_CHECK_FUNCS(rad_create_request)
fi
AC_MSG_CHECKING(if --with-libpam option is specified)
AC_ARG_WITH(libpam,
[ --with-libpam=DIR specify libpam path (like/usr/pkg)],
[libpam_dir=$withval],
[libpam_dir=no])
AC_MSG_RESULT($libpam_dir)
if test "$libpam_dir" != "no"; then
if test "$libpam_dir" = "yes" ; then
libpam_dir="";
fi;
if test "x$libpam_dir" = "x"; then
RACOON_PATH_LIBS(rad_create_request, lpam)
else
if test -d "$libpam_dir/lib" -a \
-d "$libpam_dir/include" ; then
RACOON_PATH_LIBS(rad_create_request, lpam, "$libpam_dir/lib")
CPPFLAGS_ADD="$CPPFLAGS_ADD -I$libpam_dir/include"
else
AC_MSG_ERROR([PAM libs or includes not found. Aborting.])
fi
fi
AC_DEFINE([HAVE_LIBPAM], [], [Hybrid authentication uses PAM])
LIBS="$LIBS -L$libpam_dir/lib -R$libpam_dir/lib -lpam"
AC_CHECK_FUNCS(rad_create_request)
fi
AC_MSG_CHECKING(if --enable-stats option is specified)
AC_ARG_ENABLE(stats,
[ --enable-stats enable statistics logging function],
[], [enable_stats=no])
if test "x$enable_stats" = "xyes"; then
AC_DEFINE([ENABLE_STATS], [], [Enable statictics])
fi
AC_MSG_RESULT($enable_stats)
AC_MSG_CHECKING(if --enable-dpd option is specified)
AC_ARG_ENABLE(dpd,
[ --enable-dpd enable dead peer detection],
[], [enable_dpd=no])
if test "x$enable_dpd" = "xyes"; then
AC_DEFINE([ENABLE_DPD], [], [Enable dead peer detection])
fi
AC_MSG_RESULT($enable_dpd)
AC_MSG_CHECKING(if --enable-samode-unspec option is specified)
AC_ARG_ENABLE(samode-unspec,
[ --enable-samode-unspec enable to use unspecified a mode of SA],
[], [enable_samode_unspec=no])
if test "x$enable_samode_unspec" = "xyes"; then
AC_DEFINE([ENABLE_SAMODE_UNSPECIFIED], [], [Enable samode-unspec])
fi
AC_MSG_RESULT($enable_samode_unspec)
# Checks if IPv6 is requested
AC_MSG_CHECKING([whether to enable ipv6])
AC_ARG_ENABLE(ipv6,
[ --disable-ipv6 disable ipv6 support],
[ case "$enableval" in
no)
AC_MSG_RESULT(no)
ipv6=no
;;
*) AC_MSG_RESULT(yes)
ipv6=yes
;;
esac ],
AC_TRY_RUN([ /* AF_INET6 avalable check */
#include <sys/types.h>
#include <sys/socket.h>
main()
{
exit(0);
if (socket(AF_INET6, SOCK_STREAM, 0) < 0)
exit(1);
else
exit(0);
}
],
AC_MSG_RESULT(yes)
AC_DEFINE([INET6], [], [Support IPv6])
ipv6=yes,
AC_MSG_RESULT(no)
ipv6=no,
AC_MSG_RESULT(no)
ipv6=no
))
if test "$ipv6" = "yes"; then
AC_MSG_CHECKING(for advanced API support)
AC_TRY_COMPILE([#ifndef INET6
#define INET6
#endif
#include <sys/types.h>
#include <netinet/in.h>],
[struct in6_pktinfo a;],
[AC_MSG_RESULT(yes)
AC_DEFINE([INET6_ADVAPI], [], [Use advanced IPv6 API])],
[AC_MSG_RESULT(no)])
fi
RACOON_CHECK_BUGGY_GETADDRINFO
if test "$buggygetaddrinfo" = "yes"; then
AC_MSG_ERROR([Broken getaddrinfo() is no longer supported. Aborting.])
fi
# Check if kernel support is available for NAT-T, defaults to no.
kernel_natt="no"
AC_MSG_CHECKING(kernel NAT-Traversal support)
case $host_os in
linux*)
# Linux kernel NAT-T check
AC_EGREP_CPP(yes,
[#include <linux/pfkeyv2.h>
#ifdef SADB_X_EXT_NAT_T_TYPE
yes
#endif
], [kernel_natt="yes"])
;;
freebsd*|netbsd*)
# NetBSD case
# Same check for FreeBSD
AC_CHECK_MEMBER(struct sadb_x_nat_t_type.sadb_x_nat_t_type_len,
[kernel_natt="yes"],, [
#define _KERNEL
#include <sys/types.h>
#include <net/pfkeyv2.h>
])
;;
esac
AC_MSG_RESULT($kernel_natt)
AC_MSG_CHECKING(whether to support NAT-T)
AC_ARG_ENABLE(natt,
[ --enable-natt enable NAT-Traversal (yes/no/kernel)],
[if test "$enable_natt" = "kernel"; then enable_natt=$kernel_natt; fi],
[enable_natt=$kernel_natt])
AC_MSG_RESULT($enable_natt)
if test "$enable_natt" = "yes"; then
if test "$kernel_natt" = "no" ; then
AC_MSG_ERROR([NAT-T requested, but no kernel support! Aborting.])
else
AC_DEFINE([ENABLE_NATT], [], [Enable NAT-Traversal])
NATT_OBJS="nattraversal.o"
AC_SUBST(NATT_OBJS)
fi
fi
AC_ARG_ENABLE(natt_00,
[ --enable-natt_00 enable NAT-Traversal Draft 00 (yes/no)],
[],
[enable_natt_00=no])
if test "$enable_natt_00" = "yes"; then
AC_DEFINE([ENABLE_NATT_00], [], [Enable NAT-Traversal draft 00])
fi
AC_ARG_ENABLE(natt_01,
[ --enable-natt_01 enable NAT-Traversal Draft 01 (yes/no)],
[],
[enable_natt_01=no])
if test "$enable_natt_01" = "yes"; then
AC_DEFINE([ENABLE_NATT_01], [], [Enable NAT-Traversal draft 01])
fi
AC_ARG_ENABLE(natt_02,
[ --enable-natt_02 enable NAT-Traversal Draft 02 (yes/no)],
[],
[enable_natt_02=no])
if test "$enable_natt_02" = "yes"; then
AC_DEFINE([ENABLE_NATT_02], [], [Enable NAT-Traversal draft 02])
fi
AC_ARG_ENABLE(natt_03,
[ --enable-natt_03 enable NAT-Traversal Draft 03 (yes/no)],
[],
[enable_natt_03=no])
if test "$enable_natt_03" = "yes"; then
AC_DEFINE([ENABLE_NATT_03], [], [Enable NAT-Traversal draft 03])
fi
AC_ARG_ENABLE(natt_04,
[ --enable-natt_04 enable NAT-Traversal Draft 04 (yes/no)],
[],
[enable_natt_05=no])
if test "$enable_natt_04" = "yes"; then
AC_DEFINE([ENABLE_NATT_04], [], [Enable NAT-Traversal draft 04])
fi
AC_ARG_ENABLE(natt_05,
[ --enable-natt_05 enable NAT-Traversal Draft 05 (yes/no)],
[],
[enable_natt_05=no])
if test "$enable_natt_05" = "yes"; then
AC_DEFINE([ENABLE_NATT_05], [], [Enable NAT-Traversal draft 05])
fi
AC_ARG_ENABLE(natt_06,
[ --enable-natt_06 enable NAT-Traversal Draft 06 (yes/no)],
[],
[enable_natt_06=no])
if test "$enable_natt_06" = "yes"; then
AC_DEFINE([ENABLE_NATT_06], [], [Enable NAT-Traversal draft 06])
fi
AC_ARG_ENABLE(natt_07,
[ --enable-natt_07 enable NAT-Traversal Draft 07 (yes/no)],
[],
[enable_natt_07=no])
if test "$enable_natt_07" = "yes"; then
AC_DEFINE([ENABLE_NATT_07], [], [Enable NAT-Traversal draft 07])
fi
AC_ARG_ENABLE(natt_08,
[ --enable-natt_08 enable NAT-Traversal Draft 08 (yes/no)],
[],
[enable_natt_08=no])
if test "$enable_natt_08" = "yes"; then
AC_DEFINE([ENABLE_NATT_08], [], [Enable NAT-Traversal draft 08])
fi
AC_MSG_CHECKING(whether we support FWD policy)
case $host in
*linux*)
AC_TRY_COMPILE([
#include <inttypes.h>
#include <linux/ipsec.h>
], [
int fwd = IPSEC_DIR_FWD;
],
[AC_MSG_RESULT(yes)
AC_DEFINE([HAVE_POLICY_FWD], [], [Have forward policy])],
[AC_MSG_RESULT(no)])
;;
*)
AC_MSG_RESULT(no)
;;
esac
CFLAGS="$CFLAGS $CFLAGS_ADD"
CPPFLAGS="$CPPFLAGS $CPPFLAGS_ADD"
case $host in
*linux*)
# Remove KERNEL_INCLUDE from CPPFLAGS. It will
# be symlinked to src/include-glibc/linux in
# compile time.
CPPFLAGS=`echo $CPPFLAGS | sed "s,-I$KERNEL_INCLUDE,,"`
;;
esac
include_racoondir=${includedir}/racoon
AC_SUBST(include_racoondir)
AC_CONFIG_FILES([
Makefile
package_version.h
src/Makefile
src/include-glibc/Makefile
src/libipsec/Makefile
src/setkey/Makefile
src/racoon/Makefile
src/racoon/samples/psk.txt
src/racoon/samples/racoon.conf
rpm/Makefile
rpm/suse/Makefile
])
AC_OUTPUT

View File

@ -0,0 +1,5 @@
#define TOP_PACKAGE "@PACKAGE@"
#define TOP_PACKAGE_NAME "@PACKAGE_NAME@"
#define TOP_PACKAGE_VERSION "@PACKAGE_VERSION@"
#define TOP_PACKAGE_STRING "@PACKAGE_STRING@"
#define TOP_PACKAGE_URL "http://ipsec-tools.sourceforge.net"

View File

@ -0,0 +1,3 @@
Makefile
Makefile.in
ipsec-tools.spec

18
crypto/dist/ipsec-tools/rpm/Makefile.am vendored Normal file
View File

@ -0,0 +1,18 @@
SUBDIRS = suse
EXTRA_DIST = \
ipsec-tools.spec.in
all-local: ipsec-tools.spec
## We borrow guile's convention and use @-...-@ as the substitution
## brackets here, instead of the usual @...@. This prevents autoconf
## from substituting the values directly into the left-hand sides of
## the sed substitutions. *sigh*
ipsec-tools.spec: ipsec-tools.spec.in Makefile
rm -f $@.tmp
sed < $< > $@.tmp \
-e 's:@-VERSION-@:${VERSION}:'
mv $@.tmp $@
CLEANFILES = ipsec-tools.spec

View File

@ -0,0 +1,87 @@
#!/bin/sh
#
# chkconfig: 2345 08 92
# description: Starts and stops racoon and loads IPSec SPD's
#
# config: /etc/sysconfig/ipsec.spd
# config: /etc/racoon/racoon.conf
# Contributed by Kimmo Koivisto <kimmo.koivisto@surfeu.fi>
# Tested with Fedora C1
# Source function library.
. /etc/init.d/functions
RACOON=/usr/sbin/racoon
SETKEY=/sbin/setkey
IPSEC_SPD=/etc/sysconfig/ipsec.spd
VAR_SUBSYS_IPSEC=/var/lock/subsys/ipsec
if [ ! -x /usr/sbin/$RACOON ]; then
echo -n $"/usr/sbin/$RACOON does not exist."; warning; echo
exit 0
fi
start() {
# Check that SPD-file exists and load it.
if [ -f "$IPSEC_SPD" ]; then
$SETKEY -f $IPSEC_SPD
fi
$RACOON
touch $VAR_SUBSYS_IPSEC
}
stop() {
killall $RACOON 2> /dev/null
$SETKEY -FD
$SETKEY -FP
rm -f $VAR_SUBSYS_IPSEC
}
status() {
# Do not print status if lockfile is missing
if [ ! -f "$VAR_SUBSYS_IPSEC" ]; then
echo $"IPSec is stopped."
return 1
fi
if [ -f "$VAR_SUBSYS_IPSEC" ]; then
echo $"IPSec is started."
return 0
fi
}
restart() {
stop
start
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
condrestart)
[ -e "$VAR_SUBSYS_IPSEC" ] && restart
;;
status)
status
;;
*)
echo $"Usage: $0 {start|stop|restart|condrestart|status}"
exit 1
;;
esac
exit 0

View File

@ -0,0 +1,60 @@
Summary: User-space IPsec tools for the Linux IPsec implementation
Name: ipsec-tools
Version: @-VERSION-@
Release: 1
Epoch: 1
License: BSD
Group: System Environment/Base
URL: http://ipsec-tools.sourceforge.net/
Source: http://prdownloads.sourceforge.net/%{name}/%{name}-%{version}.tar.gz
Requires: kernel >= 2.5.54
#BuildRequires: kernel-source >= 2.5.54
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
%description
IPsec-Tools is a port of the KAME Project's IPsec tools to the Linux
IPsec implementation. IPsec-Tools provides racoon, an IKE daemon; libipsec,
a PFKey implementation; and setkey, a security policy and security
association database configuration utility.
%prep
%setup -q
%build
./configure --prefix=/usr --sysconfdir=/etc --exec-prefix=/ --mandir=%{_mandir} --libdir=/%{_lib}
make
%install
rm -rf %{buildroot}
mkdir %{buildroot}
make install DESTDIR=%{buildroot}
%post -p /sbin/ldconfig
%postun -p /sbin/ldconfig
%clean
rm -rf %{buildroot}
%files
%defattr(-,root,root)
%doc NEWS README ChangeLog
%dir %{_sysconfdir}/racoon
%config %{_sysconfdir}/racoon/*
/sbin/*
/%{_lib}/*
%{_includedir}/*
%{_mandir}/man[358]/*
%{_sbindir}/racoon
%changelog
* Fri Mar 07 2003 Derek Atkins <derek@ihtfp.com> 0.2.1-1
- Insert into code base. Dynamically generate the version string.
* Fri Mar 07 2003 Chris Ricker <kaboom@gatech.edu> 0.2.1-1
- Rev to 0.2.1 release
- Remove unneeded patch
* Thu Mar 06 2003 Chris Ricker <kaboom@gatech.edu> 0.2-1
- initial package

View File

@ -0,0 +1,3 @@
Makefile
Makefile.in
ipsec-tools.spec

View File

@ -0,0 +1,15 @@
EXTRA_DIST = ipsec-tools.spec.in racoon.init sysconfig.racoon
all-local: ipsec-tools.spec
## We borrow guile's convention and use @-...-@ as the substitution
## brackets here, instead of the usual @...@. This prevents autoconf
## from substituting the values directly into the left-hand sides of
## the sed substitutions. *sigh*
ipsec-tools.spec: ipsec-tools.spec.in Makefile
rm -f $@.tmp
sed < $< > $@.tmp \
-e 's:@-VERSION-@:${VERSION}:'
mv $@.tmp $@
CLEANFILES = ipsec-tools.spec

View File

@ -0,0 +1,110 @@
#
# spec file for package ipsec-tools
#
# Copyright (c) 2004 SUSE LINUX AG, Nuernberg, Germany.
# This file and all modifications and additions to the pristine
# package are under the same license as the package itself.
#
# Please submit bugfixes or comments via http://www.suse.de/feedback/
#
# norootforbuild
# neededforbuild kernel-source openssl openssl-devel readline-devel
BuildRequires: aaa_base acl attr bash bind-utils bison bzip2 coreutils cpio cpp cracklib cvs cyrus-sasl db devs diffutils e2fsprogs file filesystem fillup findutils flex gawk gdbm-devel glibc glibc-devel glibc-locale gpm grep groff gzip info insserv less libacl libattr libgcc libselinux libstdc++ libxcrypt libzio m4 make man mktemp module-init-tools ncurses ncurses-devel net-tools netcfg openldap2-client openssl pam pam-modules patch permissions popt procinfo procps psmisc pwdutils rcs readline sed strace syslogd sysvinit tar tcpd texinfo timezone unzip util-linux vim zlib zlib-devel autoconf automake binutils gcc gdbm gettext kernel-source libtool openssl-devel perl readline-devel rpm
Name: ipsec-tools
Version: @-VERSION-@
Release: 0
License: Other License(s), see package, BSD
Group: Productivity/Networking/Security
Provides: racoon
PreReq: %insserv_prereq %fillup_prereq
Autoreqprov: on
Summary: IPsec Utilities
Source: http://prdownloads.sourceforge.net/ipsec-tools/ipsec-tools-%{version}.tar.bz2
Source1: racoon.init
Source2: sysconfig.racoon
URL: http://ipsec-tools.sourceforge.net/
Prefix: /usr
BuildRoot: %{_tmppath}/%{name}-%{version}-build
%description
This is the IPsec-Tools package. This package is needed to really make
use of the IPsec functionality in the version 2.5 and 2.6 Linux
kernels. This package builds:
- libipsec, a PFKeyV2 library
- setkey, a program to directly manipulate policies and SAs
- racoon, an IKEv1 keying daemon
These sources can be found at the IPsec-Tools home page at:
http://ipsec-tools.sourceforge.net/
Authors:
--------
Derek Atkins <derek@ihtfp.com>
Michal Ludvig <mludvig@suse.cz>
%prep
%setup
%build
%{suse_update_config -f . src/racoon}
CFLAGS="$RPM_OPT_FLAGS" \
./configure --prefix=/usr --disable-shared \
--mandir=%{_mandir} --infodir=%{_infodir} --libdir=%{_libdir} \
--libexecdir=%{_libdir} --sysconfdir=/etc/racoon \
--sharedstatedir=/var/run --localstatedir=/var \
--enable-dpd --enable-hybrid --enable-frag
make
make check
%install
rm -rf $RPM_BUILD_ROOT
make install DESTDIR=$RPM_BUILD_ROOT
mkdir -p $RPM_BUILD_ROOT/etc/init.d
install -m 0755 $RPM_SOURCE_DIR/racoon.init $RPM_BUILD_ROOT/etc/init.d/racoon
ln -sf /etc/init.d/racoon $RPM_BUILD_ROOT/usr/sbin/rcracoon
mkdir -p $RPM_BUILD_ROOT/var/adm/fillup-templates
install -m 644 $RPM_SOURCE_DIR/sysconfig.racoon $RPM_BUILD_ROOT/var/adm/fillup-templates/
mkdir -p $RPM_BUILD_ROOT/usr/share/doc/packages/%{name}/
cp -rv src/racoon/samples $RPM_BUILD_ROOT/usr/share/doc/packages/%{name}/
cp -v src/setkey/sample* $RPM_BUILD_ROOT/usr/share/doc/packages/%{name}/
%post
%{fillup_and_insserv racoon}
%postun
%{insserv_cleanup}
%clean
if test ! -z "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != "/"; then
rm -rf $RPM_BUILD_ROOT
fi
%files
%defattr(-,root,root)
%dir /etc/racoon
%config(noreplace) /etc/racoon/psk.txt
%config(noreplace) /etc/racoon/racoon.conf
%config(noreplace) /etc/racoon/setkey.conf
%config /etc/init.d/racoon
/usr/sbin/rcracoon
%dir /usr/include/libipsec/
%doc /usr/share/doc/packages/%{name}/
/var/adm/fillup-templates/sysconfig.racoon
/usr/include/libipsec/libpfkey.h
/usr/%{_lib}/libipsec.a
/usr/%{_lib}/libipsec.la
/usr/sbin/racoon
/usr/sbin/racoonctl
/usr/sbin/setkey
/usr/sbin/plainrsa-gen
%{_mandir}/man*/*
%changelog -n ipsec-tools

View File

@ -0,0 +1,168 @@
#! /bin/sh
# Copyright (c) 2001-2002 SuSE GmbH Nuernberg, Germany.
#
# Author: Michal Ludvig <feedback@suse.de>, 2004
#
# /etc/init.d/ipsec-tools
# and its symbolic link
# /usr/sbin/rcipsec-tools
#
# System startup script for the IPsec key management daemon
#
### BEGIN INIT INFO
# Provides: racoon
# Required-Start: $remote_fs $named $syslog
# Required-Stop: $remote_fs $named $syslog
# Default-Start: 3 5
# Default-Stop: 0 1 2 6
# Description: IPsec key management daemon
### END INIT INFO
SETKEY="IPsec policies"
SETKEY_BIN=/usr/sbin/setkey
SETKEY_CONF=/etc/racoon/setkey.conf
RACOON="IPsec IKE daemon (racoon)"
RACOON_BIN=/usr/sbin/racoon
RACOON_CONF=/etc/racoon/racoon.conf
RACOON_PIDFILE=/var/run/racoon.pid
test -x $SETKEY_BIN || exit 5
test -x $RACOON_BIN || exit 5
test -f /etc/sysconfig/racoon && . /etc/sysconfig/racoon
# Shell functions sourced from /etc/rc.status:
# rc_check check and set local and overall rc status
# rc_status check and set local and overall rc status
# rc_status -v ditto but be verbose in local rc status
# rc_status -v -r ditto and clear the local rc status
# rc_failed set local and overall rc status to failed
# rc_failed <num> set local and overall rc status to <num><num>
# rc_reset clear local rc status (overall remains)
# rc_exit exit appropriate to overall rc status
. /etc/rc.status
# First reset status of this service
rc_reset
# Return values acc. to LSB for all commands but status:
# 0 - success
# 1 - generic or unspecified error
# 2 - invalid or excess argument(s)
# 3 - unimplemented feature (e.g. "reload")
# 4 - insufficient privilege
# 5 - program is not installed
# 6 - program is not configured
# 7 - program is not running
#
# Note that starting an already running service, stopping
# or restarting a not-running service as well as the restart
# with force-reload (in case signalling is not supported) are
# considered a success.
case "$1" in
start)
# Setting up SPD policies is not required.
if [ -f $SETKEY_CONF ]; then
echo -n "Setting up $SETKEY"
$SETKEY_BIN $SETKEY_OPTIONS -f $SETKEY_CONF
rc_status -v
rc_reset
fi
echo -n "Starting $RACOON "
## If there is no conf file, skip starting of ddtd
## and return with "program not configured"
if ! [ -f $RACOON_CONF ]; then
echo -e -n "... no configuration file found"
rc_status -s
# service is not configured
rc_failed 6
rc_exit
fi
# startproc should return 0, even if service is
# already running to match LSB spec.
startproc $RACOON_BIN $RACOON_OPTIONS -f $RACOON_CONF
rc_status -v
;;
stop)
echo -n "Shutting down $RACOON"
## Stop daemon with killproc(8) and if this fails
## set echo the echo return value.
killproc -p $RACOON_PIDFILE -TERM $RACOON_BIN
# Remember status and be verbose
rc_status -v
rc_reset
# Flush SPD policies if required
if [ -n "$SETKEY_FLUSH_OPTIONS" ]; then
echo -n "Flushing $SETKEY"
$SETKEY_BIN $SETKEY_FLUSH_OPTIONS
rc_status -v
fi
;;
try-restart)
## Stop the service and if this succeeds (i.e. the
## service was running before), start it again.
$0 stop && $0 start
# Remember status and be quiet
rc_status
;;
restart)
## Stop the service and regardless of whether it was
## running or not, start it again.
$0 stop
$0 start
# Remember status and be quiet
rc_status
;;
force-reload)
## Signal the daemon to reload its config. Most daemons
## do this on signal 1 (SIGHUP).
## If it does not support it, restart.
echo -n "Reload service $RACOON"
killproc -p $RACOON_PIDFILE -HUP $RACOON_BIN
rc_status -v
;;
reload)
## Like force-reload, but if daemon does not support
## signalling, do nothing (!)
echo -n "Reload service $RACOON"
killproc -p $RACOON_PIDFILE -HUP $RACOON_BIN
rc_status -v
;;
status)
echo -n "Checking for $RACOON: "
## Check status with checkproc(8), if process is running
## checkproc will return with exit status 0.
# Status has a slightly different for the status command:
# 0 - service running
# 1 - service dead, but /var/run/ pid file exists
# 2 - service dead, but /var/lock/ lock file exists
# 3 - service not running
checkproc -p $RACOON_PIDFILE $RACOON_BIN
rc_status -v
;;
probe)
## Optional: Probe for the necessity of a reload,
## give out the argument which is required for a reload.
test "$RACOON_CONF" -nt "$RACOON_PIDFILE" && echo reload
;;
*)
echo "Usage: $0 {start|stop|status|try-restart|restart|force-reload|reload|probe}"
exit 1
;;
esac
rc_exit

View File

@ -0,0 +1,24 @@
## Path: Network/IPsec
## Description: IPsec keying daemon (IKE)
## Type: string
## Default: "-v"
#
# Start-up flags for the racoon dameon.
#
RACOON_OPTIONS="-v"
## Path: Network/IPsec
## Description: Tool for manipulation IPsec SPD and SA databases
## Type: string
## Default: ""
#
# Additional flags uset when inserting SPD rules.
#
SETKEY_OPTIONS=""
## Type: string
## Default: "-FP"
#
# Flags to flush SPD on racoon exit.
#
SETKEY_FLUSH_OPTIONS="-FP"

View File

@ -0,0 +1,2 @@
Makefile
Makefile.in

View File

@ -0,0 +1 @@
SUBDIRS = @INCLUDE_GLIBC@ libipsec setkey racoon

View File

@ -0,0 +1,3 @@
Makefile
Makefile.in
.includes

View File

@ -0,0 +1,14 @@
.includes: ${top_builddir}/config.status
ln -sf $(KERNEL_INCLUDE)/linux
touch .includes
all: .includes
EXTRA_DIST = \
glibc-bugs.h \
net/pfkeyv2.h \
netinet/ipsec.h \
sys/queue.h
DISTCLEANFILES = .includes linux

View File

@ -0,0 +1,10 @@
#ifndef __GLIBC_BUGS_H__
#define __GLIBC_BUGS_H__ 1
#define _XOPEN_SOURCE 500
#define _BSD_SOURCE
#include <features.h>
#include <sys/types.h>
#endif

View File

@ -0,0 +1,69 @@
#ifndef __NET_PFKEYV2_H_
#define __NET_PFKEYV2_H_ 1
#include <stdint.h>
#include <linux/pfkeyv2.h>
/* Private allocations for authentication algorithms */
#define SADB_AALG_SHA2_256 SADB_X_AALG_SHA2_256HMAC
#define SADB_X_AALG_SHA2_256 SADB_X_AALG_SHA2_256HMAC
#define SADB_AALG_SHA2_384 SADB_X_AALG_SHA2_384HMAC
#define SADB_X_AALG_SHA2_384 SADB_X_AALG_SHA2_384HMAC
#define SADB_AALG_SHA2_512 SADB_X_AALG_SHA2_512HMAC
#define SADB_X_AALG_SHA2_512 SADB_X_AALG_SHA2_512HMAC
#define SADB_AALG_RIPEMD160HMAC SADB_X_AALG_RIPEMD160HMAC
#define SADB_X_AALG_MD5 249
#define SADB_X_AALG_SHA 250
/* private allocations - based on RFC2407/IANA assignment */
#define SADB_X_EALG_CAST128CBC 5 /* SADB_X_EALG_CASTCBC? == 6 */
#define SADB_X_EALG_RIJNDAELCBC SADB_X_EALG_AESCBC
#define SADB_X_EALG_AES SADB_X_EALG_AESCBC
#define SADB_X_CALG_NONE 0
#define SADB_X_CALG_OUI 1
#define SADB_X_CALG_DEFLATE 2
#define SADB_X_CALG_LZS 3
#define SADB_X_CALG_MAX 4
#define SADB_X_EXT_NONE 0x0000 /* i.e. new format. */
#define SADB_X_EXT_OLD 0x0001 /* old format. */
#define SADB_X_EXT_IV4B 0x0010 /* IV length of 4 bytes in use */
#define SADB_X_EXT_DERIV 0x0020 /* DES derived */
#define SADB_X_EXT_CYCSEQ 0x0040 /* allowing to cyclic sequence. */
/* three of followings are exclusive flags each them */
#define SADB_X_EXT_PSEQ 0x0000 /* sequencial padding for ESP */
#define SADB_X_EXT_PRAND 0x0100 /* random padding for ESP */
#define SADB_X_EXT_PZERO 0x0200 /* zero padding for ESP */
#define SADB_X_EXT_PMASK 0x0300 /* mask for padding flag */
#define SADB_X_EXT_RAWCPI 0x0080 /* use well known CPI (IPComp) */
#define PFKEY_SOFT_LIFETIME_RATE 80
#define SADB_X_LIFETIME_ALLOCATIONS 0
#define SADB_X_LIFETIME_BYTES 1
#define SADB_X_LIFETIME_ADDTIME 2
#define SADB_X_LIFETIME_USETIME 3
#define PFKEY_ALIGN8(a) (1 + (((a) - 1) | (8 - 1)))
#define PFKEY_EXTLEN(msg) \
PFKEY_UNUNIT64(((struct sadb_ext *)(msg))->sadb_ext_len)
#define PFKEY_ADDR_PREFIX(ext) \
(((struct sadb_address *)(ext))->sadb_address_prefixlen)
#define PFKEY_ADDR_PROTO(ext) \
(((struct sadb_address *)(ext))->sadb_address_proto)
#define PFKEY_ADDR_SADDR(ext) \
((struct sockaddr *)((caddr_t)(ext) + sizeof(struct sadb_address)))
/* in 64bits */
#define PFKEY_UNUNIT64(a) ((a) << 3)
#define PFKEY_UNIT64(a) ((a) >> 3)
#endif

View File

@ -0,0 +1,2 @@
#include <net/pfkeyv2.h>
#include <linux/ipsec.h>

View File

@ -0,0 +1,452 @@
/*
* Copyright (c) 1991, 1993
* The Regents of the University of California. 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.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
*
* @(#)queue.h 8.5 (Berkeley) 8/20/94
* $FreeBSD: src/sys/sys/queue.h,v 1.58 2004/04/07 04:19:49 imp Exp $
*
* 04/24/2004 Backport to v1.45 functionality for ipsec-tools
* Heiko Hund <heiko@ist.eigentlich.net>
*/
#ifndef _SYS_QUEUE_H_
#define _SYS_QUEUE_H_
//#include <sys/cdefs.h>
/*
* This file defines four types of data structures: singly-linked lists,
* singly-linked tail queues, lists and tail queues.
*
* A singly-linked list is headed by a single forward pointer. The elements
* are singly linked for minimum space and pointer manipulation overhead at
* the expense of O(n) removal for arbitrary elements. New elements can be
* added to the list after an existing element or at the head of the list.
* Elements being removed from the head of the list should use the explicit
* macro for this purpose for optimum efficiency. A singly-linked list may
* only be traversed in the forward direction. Singly-linked lists are ideal
* for applications with large datasets and few or no removals or for
* implementing a LIFO queue.
*
* A singly-linked tail queue is headed by a pair of pointers, one to the
* head of the list and the other to the tail of the list. The elements are
* singly linked for minimum space and pointer manipulation overhead at the
* expense of O(n) removal for arbitrary elements. New elements can be added
* to the list after an existing element, at the head of the list, or at the
* end of the list. Elements being removed from the head of the tail queue
* should use the explicit macro for this purpose for optimum efficiency.
* A singly-linked tail queue may only be traversed in the forward direction.
* Singly-linked tail queues are ideal for applications with large datasets
* and few or no removals or for implementing a FIFO queue.
*
* A list is headed by a single forward pointer (or an array of forward
* pointers for a hash table header). The elements are doubly linked
* so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before
* or after an existing element or at the head of the list. A list
* may only be traversed in the forward direction.
*
* A tail queue is headed by a pair of pointers, one to the head of the
* list and the other to the tail of the list. The elements are doubly
* linked so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before or
* after an existing element, at the head of the list, or at the end of
* the list. A tail queue may be traversed in either direction.
*
* For details on the use of these macros, see the queue(3) manual page.
*
*
* SLIST LIST STAILQ TAILQ
* _HEAD + + + +
* _HEAD_INITIALIZER + + + +
* _ENTRY + + + +
* _INIT + + + +
* _EMPTY + + + +
* _FIRST + + + +
* _NEXT + + + +
* _PREV - - - +
* _LAST - - + +
* _FOREACH + + + +
* _FOREACH_REVERSE - - - +
* _INSERT_HEAD + + + +
* _INSERT_BEFORE - + - +
* _INSERT_AFTER + + + +
* _INSERT_TAIL - - + +
* _REMOVE_HEAD + - + -
* _REMOVE + + + +
*
*/
/*
* Singly-linked List declarations.
*/
#define SLIST_HEAD(name, type) \
struct name { \
struct type *slh_first; /* first element */ \
}
#define SLIST_HEAD_INITIALIZER(head) \
{ NULL }
#define SLIST_ENTRY(type) \
struct { \
struct type *sle_next; /* next element */ \
}
/*
* Singly-linked List functions.
*/
#define SLIST_EMPTY(head) ((head)->slh_first == NULL)
#define SLIST_FIRST(head) ((head)->slh_first)
#define SLIST_FOREACH(var, head, field) \
for ((var) = SLIST_FIRST((head)); \
(var); \
(var) = SLIST_NEXT((var), field))
#define SLIST_INIT(head) do { \
SLIST_FIRST((head)) = NULL; \
} while (0)
#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \
SLIST_NEXT((slistelm), field) = (elm); \
} while (0)
#define SLIST_INSERT_HEAD(head, elm, field) do { \
SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \
SLIST_FIRST((head)) = (elm); \
} while (0)
#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
#define SLIST_REMOVE(head, elm, type, field) do { \
if (SLIST_FIRST((head)) == (elm)) { \
SLIST_REMOVE_HEAD((head), field); \
} \
else { \
struct type *curelm = SLIST_FIRST((head)); \
while (SLIST_NEXT(curelm, field) != (elm)) \
curelm = SLIST_NEXT(curelm, field); \
SLIST_NEXT(curelm, field) = \
SLIST_NEXT(SLIST_NEXT(curelm, field), field); \
} \
} while (0)
#define SLIST_REMOVE_HEAD(head, field) do { \
SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \
} while (0)
/*
* Singly-linked Tail queue declarations.
*/
#define STAILQ_HEAD(name, type) \
struct name { \
struct type *stqh_first;/* first element */ \
struct type **stqh_last;/* addr of last next element */ \
}
#define STAILQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).stqh_first }
#define STAILQ_ENTRY(type) \
struct { \
struct type *stqe_next; /* next element */ \
}
/*
* Singly-linked Tail queue functions.
*/
#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
#define STAILQ_FIRST(head) ((head)->stqh_first)
#define STAILQ_FOREACH(var, head, field) \
for((var) = STAILQ_FIRST((head)); \
(var); \
(var) = STAILQ_NEXT((var), field))
#define STAILQ_INIT(head) do { \
STAILQ_FIRST((head)) = NULL; \
(head)->stqh_last = &STAILQ_FIRST((head)); \
} while (0)
#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \
if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
STAILQ_NEXT((tqelm), field) = (elm); \
} while (0)
#define STAILQ_INSERT_HEAD(head, elm, field) do { \
if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
STAILQ_FIRST((head)) = (elm); \
} while (0)
#define STAILQ_INSERT_TAIL(head, elm, field) do { \
STAILQ_NEXT((elm), field) = NULL; \
*(head)->stqh_last = (elm); \
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
} while (0)
#define STAILQ_LAST(head, type, field) \
(STAILQ_EMPTY(head) ? \
NULL : \
((struct type *) \
((char *)((head)->stqh_last) - __offsetof(struct type, field))))
#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
#define STAILQ_REMOVE(head, elm, type, field) do { \
if (STAILQ_FIRST((head)) == (elm)) { \
STAILQ_REMOVE_HEAD(head, field); \
} \
else { \
struct type *curelm = STAILQ_FIRST((head)); \
while (STAILQ_NEXT(curelm, field) != (elm)) \
curelm = STAILQ_NEXT(curelm, field); \
if ((STAILQ_NEXT(curelm, field) = \
STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) == NULL)\
(head)->stqh_last = &STAILQ_NEXT((curelm), field);\
} \
} while (0)
#define STAILQ_REMOVE_HEAD(head, field) do { \
if ((STAILQ_FIRST((head)) = \
STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \
(head)->stqh_last = &STAILQ_FIRST((head)); \
} while (0)
#define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do { \
if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL) \
(head)->stqh_last = &STAILQ_FIRST((head)); \
} while (0)
/*
* List declarations.
*/
#define LIST_HEAD(name, type) \
struct name { \
struct type *lh_first; /* first element */ \
}
#define LIST_HEAD_INITIALIZER(head) \
{ NULL }
#define LIST_ENTRY(type) \
struct { \
struct type *le_next; /* next element */ \
struct type **le_prev; /* address of previous next element */ \
}
/*
* List functions.
*/
#define LIST_EMPTY(head) ((head)->lh_first == NULL)
#define LIST_FIRST(head) ((head)->lh_first)
#define LIST_FOREACH(var, head, field) \
for ((var) = LIST_FIRST((head)); \
(var); \
(var) = LIST_NEXT((var), field))
#define LIST_INIT(head) do { \
LIST_FIRST((head)) = NULL; \
} while (0)
#define LIST_INSERT_AFTER(listelm, elm, field) do { \
if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
LIST_NEXT((listelm), field)->field.le_prev = \
&LIST_NEXT((elm), field); \
LIST_NEXT((listelm), field) = (elm); \
(elm)->field.le_prev = &LIST_NEXT((listelm), field); \
} while (0)
#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
(elm)->field.le_prev = (listelm)->field.le_prev; \
LIST_NEXT((elm), field) = (listelm); \
*(listelm)->field.le_prev = (elm); \
(listelm)->field.le_prev = &LIST_NEXT((elm), field); \
} while (0)
#define LIST_INSERT_HEAD(head, elm, field) do { \
if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \
LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
LIST_FIRST((head)) = (elm); \
(elm)->field.le_prev = &LIST_FIRST((head)); \
} while (0)
#define LIST_NEXT(elm, field) ((elm)->field.le_next)
#define LIST_REMOVE(elm, field) do { \
if (LIST_NEXT((elm), field) != NULL) \
LIST_NEXT((elm), field)->field.le_prev = \
(elm)->field.le_prev; \
*(elm)->field.le_prev = LIST_NEXT((elm), field); \
} while (0)
/*
* Tail queue declarations.
*/
#define TAILQ_HEAD(name, type) \
struct name { \
struct type *tqh_first; /* first element */ \
struct type **tqh_last; /* addr of last next element */ \
}
#define TAILQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).tqh_first }
#define TAILQ_ENTRY(type) \
struct { \
struct type *tqe_next; /* next element */ \
struct type **tqe_prev; /* address of previous next element */ \
}
/*
* Tail queue functions.
*/
#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
#define TAILQ_FIRST(head) ((head)->tqh_first)
#define TAILQ_FOREACH(var, head, field) \
for ((var) = TAILQ_FIRST((head)); \
(var); \
(var) = TAILQ_NEXT((var), field))
#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
for ((var) = TAILQ_LAST((head), headname); \
(var); \
(var) = TAILQ_PREV((var), headname, field))
#define TAILQ_INIT(head) do { \
TAILQ_FIRST((head)) = NULL; \
(head)->tqh_last = &TAILQ_FIRST((head)); \
} while (0)
#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\
TAILQ_NEXT((elm), field)->field.tqe_prev = \
&TAILQ_NEXT((elm), field); \
else \
(head)->tqh_last = &TAILQ_NEXT((elm), field); \
TAILQ_NEXT((listelm), field) = (elm); \
(elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \
} while (0)
#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
TAILQ_NEXT((elm), field) = (listelm); \
*(listelm)->field.tqe_prev = (elm); \
(listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \
} while (0)
#define TAILQ_INSERT_HEAD(head, elm, field) do { \
if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \
TAILQ_FIRST((head))->field.tqe_prev = \
&TAILQ_NEXT((elm), field); \
else \
(head)->tqh_last = &TAILQ_NEXT((elm), field); \
TAILQ_FIRST((head)) = (elm); \
(elm)->field.tqe_prev = &TAILQ_FIRST((head)); \
} while (0)
#define TAILQ_INSERT_TAIL(head, elm, field) do { \
TAILQ_NEXT((elm), field) = NULL; \
(elm)->field.tqe_prev = (head)->tqh_last; \
*(head)->tqh_last = (elm); \
(head)->tqh_last = &TAILQ_NEXT((elm), field); \
} while (0)
#define TAILQ_LAST(head, headname) \
(*(((struct headname *)((head)->tqh_last))->tqh_last))
#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
#define TAILQ_PREV(elm, headname, field) \
(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
#define TAILQ_REMOVE(head, elm, field) do { \
if ((TAILQ_NEXT((elm), field)) != NULL) \
TAILQ_NEXT((elm), field)->field.tqe_prev = \
(elm)->field.tqe_prev; \
else \
(head)->tqh_last = (elm)->field.tqe_prev; \
*(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \
} while (0)
#ifdef _KERNEL
/*
* XXX insque() and remque() are an old way of handling certain queues.
* They bogusly assumes that all queue heads look alike.
*/
struct quehead {
struct quehead *qh_link;
struct quehead *qh_rlink;
};
#ifdef __GNUC__
static __inline void
insque(void *a, void *b)
{
struct quehead *element = (struct quehead *)a,
*head = (struct quehead *)b;
element->qh_link = head->qh_link;
element->qh_rlink = head;
head->qh_link = element;
element->qh_link->qh_rlink = element;
}
static __inline void
remque(void *a)
{
struct quehead *element = (struct quehead *)a;
element->qh_link->qh_rlink = element->qh_rlink;
element->qh_rlink->qh_link = element->qh_link;
element->qh_rlink = 0;
}
#else /* !__GNUC__ */
void insque __P((void *a, void *b));
void remque __P((void *a));
#endif /* __GNUC__ */
#endif /* _KERNEL */
#endif /* !_SYS_QUEUE_H_ */

View File

@ -0,0 +1,9 @@
policy_parse.c
policy_parse.h
policy_token.c
Makefile
Makefile.in
.libs
.deps
*.la
*.lo

View File

@ -0,0 +1,39 @@
#bin_PROGRAMS = test-policy test-policy-priority
lib_LTLIBRARIES = libipsec.la
libipsecdir = $(includedir)/libipsec
libipsec_HEADERS = libpfkey.h
man3_MANS = ipsec_set_policy.3 ipsec_strerror.3
AM_CFLAGS = @GLIBC_BUGS@
AM_YFLAGS = -d -p __libipsec
AM_LFLAGS = -P__libipsec -olex.yy.c
libipsec_la_SOURCES = \
ipsec_dump_policy.c \
ipsec_get_policylen.c \
ipsec_strerror.c \
key_debug.c \
pfkey.c \
pfkey_dump.c \
policy_parse.y \
policy_token.l
# version is current:revision:age.
# See: http://www.gnu.org/manual/libtool-1.4.2/html_chapter/libtool_6.html#SEC32
libipsec_la_LDFLAGS = -version-info 0:0:0
libipsec_la_LIBADD = $(LEXLIB)
noinst_HEADERS = ipsec_strerror.h policy_parse.h
#test_policy_SOURCES = test-policy.c
#test_policy_LDFLAGS = libipsec.la
#test_policy_priority_SOURCES = test-policy-priority.c
#test_policy_priority_LDFLAGS = libipsec.la
EXTRA_DIST = ${man3_MANS} test-policy.c
DISTCLEANFILES = policy_parse.c policy_parse.h policy_token.c policy_token.h

View File

@ -0,0 +1,387 @@
/* $Id: ipsec_dump_policy.c,v 1.1.1.1 2005/02/12 11:11:23 manu Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <netinet/in.h>
#ifdef HAVE_NETINET6_IPSEC
# include <netinet6/ipsec.h>
#else
# include <netinet/ipsec.h>
#endif
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include "ipsec_strerror.h"
#include "libpfkey.h"
static const char *ipsp_dir_strs[] = {
"any", "in", "out", "fwd"
};
static const char *ipsp_policy_strs[] = {
"discard", "none", "ipsec", "entrust", "bypass",
};
static char *ipsec_dump_ipsecrequest __P((char *, size_t,
struct sadb_x_ipsecrequest *, size_t));
static int set_addresses __P((char *, size_t, struct sockaddr *,
struct sockaddr *));
static char *set_address __P((char *, size_t, struct sockaddr *));
/*
* policy is sadb_x_policy buffer.
* Must call free() later.
* When delimiter == NULL, alternatively ' '(space) is applied.
*/
char *
ipsec_dump_policy(policy, delimiter)
caddr_t policy;
char *delimiter;
{
struct sadb_x_policy *xpl = (struct sadb_x_policy *)policy;
struct sadb_x_ipsecrequest *xisr;
size_t off, buflen;
char *buf;
char isrbuf[1024];
char *newbuf;
#ifdef HAVE_PFKEY_POLICY_PRIORITY
int32_t priority_offset;
char *priority_str;
char operator;
#endif
/* sanity check */
if (policy == NULL)
return NULL;
if (xpl->sadb_x_policy_exttype != SADB_X_EXT_POLICY) {
__ipsec_errcode = EIPSEC_INVAL_EXTTYPE;
return NULL;
}
/* set delimiter */
if (delimiter == NULL)
delimiter = " ";
#ifdef HAVE_PFKEY_POLICY_PRIORITY
if (xpl->sadb_x_policy_priority == 0)
{
priority_offset = 0;
priority_str = "";
}
/* find which constant the priority is closest to */
else if (xpl->sadb_x_policy_priority <
(u_int32_t) (PRIORITY_DEFAULT / 4) * 3)
{
priority_offset = xpl->sadb_x_policy_priority - PRIORITY_HIGH;
priority_str = "prio high";
}
else if (xpl->sadb_x_policy_priority >=
(u_int32_t) (PRIORITY_DEFAULT / 4) * 3 &&
xpl->sadb_x_policy_priority <
(u_int32_t) (PRIORITY_DEFAULT / 4) * 5)
{
priority_offset = xpl->sadb_x_policy_priority - PRIORITY_DEFAULT;
priority_str = "prio def";
}
else
{
priority_offset = xpl->sadb_x_policy_priority - PRIORITY_LOW;
priority_str = "prio low";
}
/* fix sign to match the way it is input */
priority_offset *= -1;
if (priority_offset < 0)
{
operator = '-';
priority_offset *= -1;
}
else
{
operator = '+';
}
#endif
switch (xpl->sadb_x_policy_dir) {
case IPSEC_DIR_ANY:
case IPSEC_DIR_INBOUND:
case IPSEC_DIR_OUTBOUND:
#ifdef HAVE_POLICY_FWD
case IPSEC_DIR_FWD:
#endif
break;
default:
__ipsec_errcode = EIPSEC_INVAL_DIR;
return NULL;
}
switch (xpl->sadb_x_policy_type) {
case IPSEC_POLICY_DISCARD:
case IPSEC_POLICY_NONE:
case IPSEC_POLICY_IPSEC:
case IPSEC_POLICY_BYPASS:
case IPSEC_POLICY_ENTRUST:
break;
default:
__ipsec_errcode = EIPSEC_INVAL_POLICY;
return NULL;
}
buflen = strlen(ipsp_dir_strs[xpl->sadb_x_policy_dir])
+ 1 /* space */
#ifdef HAVE_PFKEY_POLICY_PRIORITY
+ strlen(priority_str)
+ ((priority_offset != 0) ? 13 : 0) /* [space operator space int] */
+ ((strlen(priority_str) != 0) ? 1 : 0) /* space */
#endif
+ strlen(ipsp_policy_strs[xpl->sadb_x_policy_type])
+ 1; /* NUL */
if ((buf = malloc(buflen)) == NULL) {
__ipsec_errcode = EIPSEC_NO_BUFS;
return NULL;
}
#ifdef HAVE_PFKEY_POLICY_PRIORITY
if (priority_offset != 0)
{
snprintf(buf, buflen, "%s %s %c %u %s",
ipsp_dir_strs[xpl->sadb_x_policy_dir], priority_str, operator,
priority_offset, ipsp_policy_strs[xpl->sadb_x_policy_type]);
}
else if (strlen (priority_str) != 0)
{
snprintf(buf, buflen, "%s %s %s",
ipsp_dir_strs[xpl->sadb_x_policy_dir], priority_str,
ipsp_policy_strs[xpl->sadb_x_policy_type]);
}
else
{
snprintf(buf, buflen, "%s %s",
ipsp_dir_strs[xpl->sadb_x_policy_dir],
ipsp_policy_strs[xpl->sadb_x_policy_type]);
}
#else
snprintf(buf, buflen, "%s %s", ipsp_dir_strs[xpl->sadb_x_policy_dir],
ipsp_policy_strs[xpl->sadb_x_policy_type]);
#endif
if (xpl->sadb_x_policy_type != IPSEC_POLICY_IPSEC) {
__ipsec_errcode = EIPSEC_NO_ERROR;
return buf;
}
/* count length of buffer for use */
off = sizeof(*xpl);
while (off < PFKEY_EXTLEN(xpl)) {
xisr = (struct sadb_x_ipsecrequest *)((caddr_t)xpl + off);
off += xisr->sadb_x_ipsecrequest_len;
}
/* validity check */
if (off != PFKEY_EXTLEN(xpl)) {
__ipsec_errcode = EIPSEC_INVAL_SADBMSG;
free(buf);
return NULL;
}
off = sizeof(*xpl);
while (off < PFKEY_EXTLEN(xpl)) {
int offset;
xisr = (struct sadb_x_ipsecrequest *)((caddr_t)xpl + off);
if (ipsec_dump_ipsecrequest(isrbuf, sizeof(isrbuf), xisr,
PFKEY_EXTLEN(xpl) - off) == NULL) {
free(buf);
return NULL;
}
offset = strlen(buf);
buflen = offset + strlen(delimiter) + strlen(isrbuf) + 1;
newbuf = (char *)realloc(buf, buflen);
if (newbuf == NULL) {
__ipsec_errcode = EIPSEC_NO_BUFS;
free(buf);
return NULL;
}
buf = newbuf;
snprintf(buf+offset, buflen-offset, "%s%s", delimiter, isrbuf);
off += xisr->sadb_x_ipsecrequest_len;
}
__ipsec_errcode = EIPSEC_NO_ERROR;
return buf;
}
static char *
ipsec_dump_ipsecrequest(buf, len, xisr, bound)
char *buf;
size_t len;
struct sadb_x_ipsecrequest *xisr;
size_t bound; /* boundary */
{
const char *proto, *mode, *level;
char abuf[NI_MAXHOST * 2 + 2];
if (xisr->sadb_x_ipsecrequest_len > bound) {
__ipsec_errcode = EIPSEC_INVAL_PROTO;
return NULL;
}
switch (xisr->sadb_x_ipsecrequest_proto) {
case IPPROTO_ESP:
proto = "esp";
break;
case IPPROTO_AH:
proto = "ah";
break;
case IPPROTO_IPCOMP:
proto = "ipcomp";
break;
default:
__ipsec_errcode = EIPSEC_INVAL_PROTO;
return NULL;
}
switch (xisr->sadb_x_ipsecrequest_mode) {
case IPSEC_MODE_ANY:
mode = "any";
break;
case IPSEC_MODE_TRANSPORT:
mode = "transport";
break;
case IPSEC_MODE_TUNNEL:
mode = "tunnel";
break;
default:
__ipsec_errcode = EIPSEC_INVAL_MODE;
return NULL;
}
abuf[0] = '\0';
if (xisr->sadb_x_ipsecrequest_len > sizeof(*xisr)) {
struct sockaddr *sa1, *sa2;
caddr_t p;
p = (caddr_t)(xisr + 1);
sa1 = (struct sockaddr *)p;
sa2 = (struct sockaddr *)(p + sysdep_sa_len(sa1));
if (sizeof(*xisr) + sysdep_sa_len(sa1) + sysdep_sa_len(sa2) !=
xisr->sadb_x_ipsecrequest_len) {
__ipsec_errcode = EIPSEC_INVAL_ADDRESS;
return NULL;
}
if (set_addresses(abuf, sizeof(abuf), sa1, sa2) != 0) {
__ipsec_errcode = EIPSEC_INVAL_ADDRESS;
return NULL;
}
}
switch (xisr->sadb_x_ipsecrequest_level) {
case IPSEC_LEVEL_DEFAULT:
level = "default";
break;
case IPSEC_LEVEL_USE:
level = "use";
break;
case IPSEC_LEVEL_REQUIRE:
level = "require";
break;
case IPSEC_LEVEL_UNIQUE:
level = "unique";
break;
default:
__ipsec_errcode = EIPSEC_INVAL_LEVEL;
return NULL;
}
if (xisr->sadb_x_ipsecrequest_reqid == 0)
snprintf(buf, len, "%s/%s/%s/%s", proto, mode, abuf, level);
else {
int ch;
if (xisr->sadb_x_ipsecrequest_reqid > IPSEC_MANUAL_REQID_MAX)
ch = '#';
else
ch = ':';
snprintf(buf, len, "%s/%s/%s/%s%c%u", proto, mode, abuf, level,
ch, xisr->sadb_x_ipsecrequest_reqid);
}
return buf;
}
static int
set_addresses(buf, len, sa1, sa2)
char *buf;
size_t len;
struct sockaddr *sa1;
struct sockaddr *sa2;
{
char tmp1[NI_MAXHOST], tmp2[NI_MAXHOST];
if (set_address(tmp1, sizeof(tmp1), sa1) == NULL ||
set_address(tmp2, sizeof(tmp2), sa2) == NULL)
return -1;
if (strlen(tmp1) + 1 + strlen(tmp2) + 1 > len)
return -1;
snprintf(buf, len, "%s-%s", tmp1, tmp2);
return 0;
}
static char *
set_address(buf, len, sa)
char *buf;
size_t len;
struct sockaddr *sa;
{
const int niflags = NI_NUMERICHOST;
if (len < 1)
return NULL;
buf[0] = '\0';
if (getnameinfo(sa, sysdep_sa_len(sa), buf, len, NULL, 0, niflags) != 0)
return NULL;
return buf;
}

View File

@ -0,0 +1,55 @@
/* $KAME: ipsec_get_policylen.c,v 1.5 2000/05/07 05:25:03 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <sys/types.h>
#include <sys/param.h>
#ifdef HAVE_NETINET6_IPSEC
# include <netinet6/ipsec.h>
#else
# include <netinet/ipsec.h>
#endif
#include <net/pfkeyv2.h>
#include "ipsec_strerror.h"
int
ipsec_get_policylen(policy)
caddr_t policy;
{
return policy ? PFKEY_EXTLEN(policy) : -1;
}

View File

@ -0,0 +1,316 @@
.\" $KAME: ipsec_set_policy.3,v 1.16 2003/01/06 21:59:03 sumikawa Exp $
.\"
.\" Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
.\" 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.
.\" 3. Neither the name of the project nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
.\"
.Dd May 5, 1998
.Dt IPSEC_SET_POLICY 3
.Os KAME
.Sh NAME
.Nm ipsec_set_policy ,
.Nm ipsec_get_policylen ,
.Nm ipsec_dump_policy
.Nd manipulate IPsec policy specification structure from readable string
.\"
.Sh LIBRARY
.Lb libipsec
.Sh SYNOPSIS
.Fd #include <netinet6/ipsec.h>
.Ft "char *"
.Fn ipsec_set_policy "char *policy" "int len"
.Ft int
.Fn ipsec_get_policylen "char *buf"
.Ft "char *"
.Fn ipsec_dump_policy "char *buf" "char *delim"
.Sh DESCRIPTION
.Fn ipsec_set_policy
generates IPsec policy specification structure, namely
.Li struct sadb_x_policy
and/or
.Li struct sadb_x_ipsecrequest
from human-readable policy specification.
policy specification must be given as C string
.Fa policy
and length
.Fa len
of
.Fa policy .
.Fn ipsec_set_policy
will return the buffer of IPsec policy specification structure.
The buffer is dynamically allocated, and must be freed by the caller by calling
.Xr free 3 .
.Pp
You may want the length of the generated buffer such when calling
.Xr setsockopt 2 .
.Fn ipsec_get_policylen
will return the length.
.Pp
.Fn ipsec_dump_policy
converts IPsec policy structure into readable form.
Therefore,
.Fn ipsec_dump_policy
can be regarded as inverse conversion of
.Fn ipsec_set_policy .
.Fa buf
points to an IPsec policy structure,
.Li struct sadb_x_policy .
.Fa delim
is a delimiter string, which is usually a blank character.
If you set
.Fa delim
to
.Dv NULL ,
single whitespace is assumed.
.Fn ipsec_dump_policy
returns pointer to dynamically allocated string.
It is caller's responsibility to reclaim the region, by using
.Xr free 3 .
.Pp
.Fa policy
is formatted as either of the following:
.Bl -tag -width "discard"
.It Ar direction [priority specification] Li discard
.Ar direction
must be
.Li in
,
.Li out
or
.Li fwd .
.Ar direction
specifies which direction the policy needs to be applied. Nonstandard
direction
.Ar fwd
is substituted with
.Ar in
on platforms which do not support forward policies.
.Pp
.Ar priority specification
is used to control the placement of the policy within the SPD. Policy position
is determined by
a signed integer where higher priorities indicate the policy is placed
closer to the beginning of the list and lower priorities indicate the
policy is placed closer to the end of the list. Policies with equal
priorities are added at the end of the group of such policies.
.Pp
Priority can only
be specified when libipsec has been compiled against kernel headers that
support policy priorities (>= 2.6.6). It takes one of the following formats:
.Bl -tag -width "discard"
.It Xo
.Ar {priority,prio} offset
.Xc
.Ar offset
is an integer in ranges -2147483647 .. 214783648.
.It Xo
.Ar {priority,prio} base {+,-} offset
.Xc
.Ar base
is either
.Li low (-1073741824),
.Li def (0),
or
.Li high (1073741824)
.Pp
.Ar offset
is an unsigned integer. It can be up to 1073741824 for
positive offsets, and up to 1073741823 for negative offsets.
.El
.Pp
The interpretation of policy priority in these functions and the kernel DOES
differ. The relationship between the two can be described as
p(kernel) = 0x80000000 - p(func)
.Pp
With
.Li discard
policy, packets will be dropped if they match the policy.
.It Ar direction [priority specification] Li entrust
.Li entrust
means to consult to SPD defined by
.Xr setkey 8 .
.It Ar direction [priority specification] Li bypass
.Li bypass
means to be bypassed the IPsec processing.
.Pq packet will be transmitted in clear .
This is for privileged socket.
.It Xo
.Ar direction
.Ar [priority specification]
.Li ipsec
.Ar request ...
.Xc
.Li ipsec
means that the matching packets are subject to IPsec processing.
.Li ipsec
can be followed by one or more
.Ar request
string, which is formatted as below:
.Bl -tag -width "discard"
.It Xo
.Ar protocol
.Li /
.Ar mode
.Li /
.Ar src
.Li -
.Ar dst
.Op Ar /level
.Xc
.Ar protocol
is either
.Li ah ,
.Li esp
or
.Li ipcomp .
.Pp
.Ar mode
is either
.Li transport
or
.Li tunnel .
.Pp
.Ar src
and
.Ar dst
specifies IPsec endpoint.
.Ar src
always means
.Dq sending node
and
.Ar dst
always means
.Dq receiving node .
Therefore, when
.Ar direction
is
.Li in ,
.Ar dst
is this node
and
.Ar src
is the other node
.Pq peer .
If
.Ar mode
is
.Li transport ,
Both
.Ar src
and
.Ar dst
can be omited.
.Pp
.Ar level
must be set to one of the following:
.Li default , use , require
or
.Li unique .
.Li default
means that the kernel should consult the system default policy
defined by
.Xr sysctl 8 ,
such as
.Li net.inet.ipsec.esp_trans_deflev .
See
.Xr ipsec 4
regarding the system default.
.Li use
means that a relevant SA can be used when available,
since the kernel may perform IPsec operation against packets when possible.
In this case, packets can be transmitted in clear
.Pq when SA is not available ,
or encrypted
.Pq when SA is available .
.Li require
means that a relevant SA is required,
since the kernel must perform IPsec operation against packets.
.Li unique
is the same as
.Li require ,
but adds the restriction that the SA for outbound traffic is used
only for this policy.
You may need the identifier in order to relate the policy and the SA
when you define the SA by manual keying.
You can put the decimal number as the identifier after
.Li unique
like
.Li unique : number .
.Li number
must be between 1 and 32767 .
If the
.Ar request
string is kept unambiguous,
.Ar level
and slash prior to
.Ar level
can be omitted.
However, it is encouraged to specify them explicitly
to avoid unintended behaviors.
If
.Ar level
is omitted, it will be interpreted as
.Li default .
.El
.Pp
Note that there is a bit difference of specification from
.Xr setkey 8 .
In specification by
.Xr setkey 8 ,
both entrust and bypass are not used.
Refer to
.Xr setkey 8
for detail.
.Pp
Here are several examples
.Pq long lines are wrapped for readability :
.Bd -literal -offset indent
in discard
out ipsec esp/transport//require
in ipsec ah/transport//require
out ipsec esp/tunnel/10.1.1.2-10.1.1.1/use
in ipsec ipcomp/transport//use
esp/transport//use
.Ed
.El
.Sh RETURN VALUES
.Fn ipsec_set_policy
returns a pointer to the allocated buffer of policy specification if successful; otherwise a NULL pointer is returned.
.Fn ipsec_get_policylen
returns with positive value
.Pq meaning the buffer size
on success, and negative value on errors.
.Fn ipsec_dump_policy
returns a pointer to dynamically allocated region on success,
and
.Dv NULL
on errors.
.Sh SEE ALSO
.Xr ipsec_strerror 3 ,
.Xr ipsec 4 ,
.Xr setkey 8
.Sh HISTORY
The functions first appeared in WIDE/KAME IPv6 protocol stack kit.

View File

@ -0,0 +1,84 @@
.\" $KAME: ipsec_strerror.3,v 1.9 2001/08/17 07:21:36 itojun Exp $
.\"
.\" Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
.\" 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.
.\" 3. Neither the name of the project nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
.\"
.Dd May 6, 1998
.Dt IPSEC_STRERROR 3
.Os KAME
.\"
.Sh NAME
.Nm ipsec_strerror
.Nd error message for IPsec policy manipulation library
.\"
.Sh SYNOPSIS
.Fd #include <netinet6/ipsec.h>
.Ft "const char *"
.Fn ipsec_strerror
.\"
.Sh DESCRIPTION
.Pa netinet6/ipsec.h
declares
.Pp
.Dl extern int ipsec_errcode;
.Pp
which is used to pass an error code from IPsec policy manipulation library
to an user program.
.Fn ipsec_strerror
can be used to obtain the error message string for the error code.
.Pp
The array pointed to is not to be modified by the program.
Since
.Fn ipsec_strerror
uses
.Xr strerror 3
as underlying function, calling
.Xr strerror 3
after
.Fn ipsec_strerror
would make the return value from
.Fn ipsec_strerror
invalid, or overwritten.
.\"
.Sh RETURN VALUES
.Fn ipsec_strerror
always return a pointer to C string.
The C string must not be overwritten by user programs.
.\"
.Sh SEE ALSO
.Xr ipsec_set_policy 3
.\"
.Sh HISTORY
.Fn ipsec_strerror
first appeared in WIDE/KAME IPv6 protocol stack kit.
.\"
.Sh BUGS
.Fn ipsec_strerror
will return its result which may be overwritten by subsequent calls.
.Pp
.Va ipsec_errcode
is not thread safe.

View File

@ -0,0 +1,98 @@
/* $KAME: ipsec_strerror.c,v 1.7 2000/07/30 00:45:12 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <sys/types.h>
#include <sys/param.h>
#include <string.h>
#ifdef HAVE_NETINET6_IPSEC
# include <netinet6/ipsec.h>
#else
# include <netinet/ipsec.h>
#endif
#include "ipsec_strerror.h"
int __ipsec_errcode;
static const char *ipsec_errlist[] = {
"Success", /*EIPSEC_NO_ERROR*/
"Not supported", /*EIPSEC_NOT_SUPPORTED*/
"Invalid argument", /*EIPSEC_INVAL_ARGUMENT*/
"Invalid sadb message", /*EIPSEC_INVAL_SADBMSG*/
"Invalid version", /*EIPSEC_INVAL_VERSION*/
"Invalid security policy", /*EIPSEC_INVAL_POLICY*/
"Invalid address specification", /*EIPSEC_INVAL_ADDRESS*/
"Invalid ipsec protocol", /*EIPSEC_INVAL_PROTO*/
"Invalid ipsec mode", /*EIPSEC_INVAL_MODE*/
"Invalid ipsec level", /*EIPSEC_INVAL_LEVEL*/
"Invalid SA type", /*EIPSEC_INVAL_SATYPE*/
"Invalid message type", /*EIPSEC_INVAL_MSGTYPE*/
"Invalid extension type", /*EIPSEC_INVAL_EXTTYPE*/
"Invalid algorithm type", /*EIPSEC_INVAL_ALGS*/
"Invalid key length", /*EIPSEC_INVAL_KEYLEN*/
"Invalid address family", /*EIPSEC_INVAL_FAMILY*/
"Invalid prefix length", /*EIPSEC_INVAL_PREFIXLEN*/
"Invalid direciton", /*EIPSEC_INVAL_DIR*/
"SPI range violation", /*EIPSEC_INVAL_SPI*/
"No protocol specified", /*EIPSEC_NO_PROTO*/
"No algorithm specified", /*EIPSEC_NO_ALGS*/
"No buffers available", /*EIPSEC_NO_BUFS*/
"Must get supported algorithms list first", /*EIPSEC_DO_GET_SUPP_LIST*/
"Protocol mismatch", /*EIPSEC_PROTO_MISMATCH*/
"Family mismatch", /*EIPSEC_FAMILY_MISMATCH*/
"Too few arguments", /*EIPSEC_FEW_ARGUMENTS*/
NULL, /*EIPSEC_SYSTEM_ERROR*/
"Priority offset not in valid range [-2147483647, 2147483648]", /*EIPSEC_INVAL_PRIORITY_OFFSET*/
"Priority offset from base not in valid range [0, 1073741823] for negative offsets and [0, 1073741824] for positive offsets", /* EIPSEC_INVAL_PRIORITY_OFFSET */
"Policy priority not compiled in", /*EIPSEC_PRIORITY_NOT_COMPILED*/
"Unknown error", /*EIPSEC_MAX*/
};
const char *ipsec_strerror(void)
{
if (__ipsec_errcode < 0 || __ipsec_errcode > EIPSEC_MAX)
__ipsec_errcode = EIPSEC_MAX;
return ipsec_errlist[__ipsec_errcode];
}
void __ipsec_set_strerror(const char *str)
{
__ipsec_errcode = EIPSEC_SYSTEM_ERROR;
ipsec_errlist[EIPSEC_SYSTEM_ERROR] = str;
return;
}

View File

@ -0,0 +1,71 @@
/* $Id: ipsec_strerror.h,v 1.1.1.1 2005/02/12 11:11:30 manu Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#ifndef _IPSEC_STRERROR_H
#define _IPSEC_STRERROR_H
extern int __ipsec_errcode;
extern void __ipsec_set_strerror __P((const char *));
#define EIPSEC_NO_ERROR 0 /*success*/
#define EIPSEC_NOT_SUPPORTED 1 /*not supported*/
#define EIPSEC_INVAL_ARGUMENT 2 /*invalid argument*/
#define EIPSEC_INVAL_SADBMSG 3 /*invalid sadb message*/
#define EIPSEC_INVAL_VERSION 4 /*invalid version*/
#define EIPSEC_INVAL_POLICY 5 /*invalid security policy*/
#define EIPSEC_INVAL_ADDRESS 6 /*invalid address specification*/
#define EIPSEC_INVAL_PROTO 7 /*invalid ipsec protocol*/
#define EIPSEC_INVAL_MODE 8 /*Invalid ipsec mode*/
#define EIPSEC_INVAL_LEVEL 9 /*invalid ipsec level*/
#define EIPSEC_INVAL_SATYPE 10 /*invalid SA type*/
#define EIPSEC_INVAL_MSGTYPE 11 /*invalid message type*/
#define EIPSEC_INVAL_EXTTYPE 12 /*invalid extension type*/
#define EIPSEC_INVAL_ALGS 13 /*Invalid algorithm type*/
#define EIPSEC_INVAL_KEYLEN 14 /*invalid key length*/
#define EIPSEC_INVAL_FAMILY 15 /*invalid address family*/
#define EIPSEC_INVAL_PREFIXLEN 16 /*SPI range violation*/
#define EIPSEC_INVAL_DIR 17 /*Invalid direciton*/
#define EIPSEC_INVAL_SPI 18 /*invalid prefixlen*/
#define EIPSEC_NO_PROTO 19 /*no protocol specified*/
#define EIPSEC_NO_ALGS 20 /*No algorithm specified*/
#define EIPSEC_NO_BUFS 21 /*no buffers available*/
#define EIPSEC_DO_GET_SUPP_LIST 22 /*must get supported algorithm first*/
#define EIPSEC_PROTO_MISMATCH 23 /*protocol mismatch*/
#define EIPSEC_FAMILY_MISMATCH 24 /*family mismatch*/
#define EIPSEC_FEW_ARGUMENTS 25 /*Too few arguments*/
#define EIPSEC_SYSTEM_ERROR 26 /*system error*/
#define EIPSEC_INVAL_PRIORITY_OFFSET 27 /*priority offset out of range*/
#define EIPSEC_INVAL_PRIORITY_BASE_OFFSET 28 /* priority base offset too
large */
#define EIPSEC_PRIORITY_NOT_COMPILED 29 /*no priority support in libipsec*/
#define EIPSEC_MAX 30 /*unknown error*/
#endif /* _IPSEC_STRERROR_H */

View File

@ -0,0 +1,817 @@
/* $KAME: key_debug.c,v 1.29 2001/08/16 14:25:41 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef _KERNEL
#if defined(__FreeBSD__) && __FreeBSD__ >= 3
#include "opt_inet.h"
#include "opt_inet6.h"
#include "opt_ipsec.h"
#endif
#ifdef __NetBSD__
#include "opt_inet.h"
#endif
#endif
#include <sys/types.h>
#include <sys/param.h>
#ifdef _KERNEL
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/queue.h>
#endif
#include <sys/socket.h>
#include <netinet/in.h>
#ifdef HAVE_NETINET6_IPSEC
# include <netinet6/ipsec.h>
#else
# include <netinet/ipsec.h>
#endif
#ifndef _KERNEL
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#endif /* !_KERNEL */
#include "config.h"
#include "libpfkey.h"
static void kdebug_sadb_prop __P((struct sadb_ext *));
static void kdebug_sadb_identity __P((struct sadb_ext *));
static void kdebug_sadb_supported __P((struct sadb_ext *));
static void kdebug_sadb_lifetime __P((struct sadb_ext *));
static void kdebug_sadb_sa __P((struct sadb_ext *));
static void kdebug_sadb_address __P((struct sadb_ext *));
static void kdebug_sadb_key __P((struct sadb_ext *));
static void kdebug_sadb_x_sa2 __P((struct sadb_ext *));
static void kdebug_sadb_x_policy __P((struct sadb_ext *ext));
static void kdebug_sockaddr __P((struct sockaddr *addr));
#ifdef SADB_X_EXT_NAT_T_TYPE
static void kdebug_sadb_x_nat_t_type __P((struct sadb_ext *ext));
static void kdebug_sadb_x_nat_t_port __P((struct sadb_ext *ext));
#endif
#ifdef _KERNEL
static void kdebug_secreplay __P((struct secreplay *));
#endif
#ifndef _KERNEL
#define panic(param) { printf(param); exit(1); }
#endif
#include "libpfkey.h"
/* NOTE: host byte order */
/* %%%: about struct sadb_msg */
void
kdebug_sadb(base)
struct sadb_msg *base;
{
struct sadb_ext *ext;
int tlen, extlen;
/* sanity check */
if (base == NULL)
panic("kdebug_sadb: NULL pointer was passed.\n");
printf("sadb_msg{ version=%u type=%u errno=%u satype=%u\n",
base->sadb_msg_version, base->sadb_msg_type,
base->sadb_msg_errno, base->sadb_msg_satype);
printf(" len=%u reserved=%u seq=%u pid=%u\n",
base->sadb_msg_len, base->sadb_msg_reserved,
base->sadb_msg_seq, base->sadb_msg_pid);
tlen = PFKEY_UNUNIT64(base->sadb_msg_len) - sizeof(struct sadb_msg);
ext = (struct sadb_ext *)((caddr_t)base + sizeof(struct sadb_msg));
while (tlen > 0) {
printf("sadb_ext{ len=%u type=%u }\n",
ext->sadb_ext_len, ext->sadb_ext_type);
if (ext->sadb_ext_len == 0) {
printf("kdebug_sadb: invalid ext_len=0 was passed.\n");
return;
}
if (ext->sadb_ext_len > tlen) {
printf("kdebug_sadb: ext_len exceeds end of buffer.\n");
return;
}
switch (ext->sadb_ext_type) {
case SADB_EXT_SA:
kdebug_sadb_sa(ext);
break;
case SADB_EXT_LIFETIME_CURRENT:
case SADB_EXT_LIFETIME_HARD:
case SADB_EXT_LIFETIME_SOFT:
kdebug_sadb_lifetime(ext);
break;
case SADB_EXT_ADDRESS_SRC:
case SADB_EXT_ADDRESS_DST:
case SADB_EXT_ADDRESS_PROXY:
kdebug_sadb_address(ext);
break;
case SADB_EXT_KEY_AUTH:
case SADB_EXT_KEY_ENCRYPT:
kdebug_sadb_key(ext);
break;
case SADB_EXT_IDENTITY_SRC:
case SADB_EXT_IDENTITY_DST:
kdebug_sadb_identity(ext);
break;
case SADB_EXT_SENSITIVITY:
break;
case SADB_EXT_PROPOSAL:
kdebug_sadb_prop(ext);
break;
case SADB_EXT_SUPPORTED_AUTH:
case SADB_EXT_SUPPORTED_ENCRYPT:
kdebug_sadb_supported(ext);
break;
case SADB_EXT_SPIRANGE:
case SADB_X_EXT_KMPRIVATE:
break;
case SADB_X_EXT_POLICY:
kdebug_sadb_x_policy(ext);
break;
case SADB_X_EXT_SA2:
kdebug_sadb_x_sa2(ext);
break;
#ifdef SADB_X_EXT_NAT_T_TYPE
case SADB_X_EXT_NAT_T_TYPE:
kdebug_sadb_x_nat_t_type(ext);
break;
case SADB_X_EXT_NAT_T_SPORT:
case SADB_X_EXT_NAT_T_DPORT:
kdebug_sadb_x_nat_t_port(ext);
break;
case SADB_X_EXT_NAT_T_OA:
kdebug_sadb_address(ext);
break;
#endif
default:
printf("kdebug_sadb: invalid ext_type %u was passed.\n",
ext->sadb_ext_type);
return;
}
extlen = PFKEY_UNUNIT64(ext->sadb_ext_len);
tlen -= extlen;
ext = (struct sadb_ext *)((caddr_t)ext + extlen);
}
return;
}
static void
kdebug_sadb_prop(ext)
struct sadb_ext *ext;
{
struct sadb_prop *prop = (struct sadb_prop *)ext;
struct sadb_comb *comb;
int len;
/* sanity check */
if (ext == NULL)
panic("kdebug_sadb_prop: NULL pointer was passed.\n");
len = (PFKEY_UNUNIT64(prop->sadb_prop_len) - sizeof(*prop))
/ sizeof(*comb);
comb = (struct sadb_comb *)(prop + 1);
printf("sadb_prop{ replay=%u\n", prop->sadb_prop_replay);
while (len--) {
printf("sadb_comb{ auth=%u encrypt=%u "
"flags=0x%04x reserved=0x%08x\n",
comb->sadb_comb_auth, comb->sadb_comb_encrypt,
comb->sadb_comb_flags, comb->sadb_comb_reserved);
printf(" auth_minbits=%u auth_maxbits=%u "
"encrypt_minbits=%u encrypt_maxbits=%u\n",
comb->sadb_comb_auth_minbits,
comb->sadb_comb_auth_maxbits,
comb->sadb_comb_encrypt_minbits,
comb->sadb_comb_encrypt_maxbits);
printf(" soft_alloc=%u hard_alloc=%u "
"soft_bytes=%lu hard_bytes=%lu\n",
comb->sadb_comb_soft_allocations,
comb->sadb_comb_hard_allocations,
(unsigned long)comb->sadb_comb_soft_bytes,
(unsigned long)comb->sadb_comb_hard_bytes);
printf(" soft_alloc=%lu hard_alloc=%lu "
"soft_bytes=%lu hard_bytes=%lu }\n",
(unsigned long)comb->sadb_comb_soft_addtime,
(unsigned long)comb->sadb_comb_hard_addtime,
(unsigned long)comb->sadb_comb_soft_usetime,
(unsigned long)comb->sadb_comb_hard_usetime);
comb++;
}
printf("}\n");
return;
}
static void
kdebug_sadb_identity(ext)
struct sadb_ext *ext;
{
struct sadb_ident *id = (struct sadb_ident *)ext;
int len;
/* sanity check */
if (ext == NULL)
panic("kdebug_sadb_identity: NULL pointer was passed.\n");
len = PFKEY_UNUNIT64(id->sadb_ident_len) - sizeof(*id);
printf("sadb_ident_%s{",
id->sadb_ident_exttype == SADB_EXT_IDENTITY_SRC ? "src" : "dst");
switch (id->sadb_ident_type) {
default:
printf(" type=%d id=%lu",
id->sadb_ident_type, (u_long)id->sadb_ident_id);
if (len) {
#ifdef _KERNEL
ipsec_hexdump((caddr_t)(id + 1), len); /*XXX cast ?*/
#else
char *p, *ep;
printf("\n str=\"");
p = (char *)(id + 1);
ep = p + len;
for (/*nothing*/; *p && p < ep; p++) {
if (isprint((int)*p))
printf("%c", *p & 0xff);
else
printf("\\%03o", *p & 0xff);
}
#endif
printf("\"");
}
break;
}
printf(" }\n");
return;
}
static void
kdebug_sadb_supported(ext)
struct sadb_ext *ext;
{
struct sadb_supported *sup = (struct sadb_supported *)ext;
struct sadb_alg *alg;
int len;
/* sanity check */
if (ext == NULL)
panic("kdebug_sadb_supported: NULL pointer was passed.\n");
len = (PFKEY_UNUNIT64(sup->sadb_supported_len) - sizeof(*sup))
/ sizeof(*alg);
alg = (struct sadb_alg *)(sup + 1);
printf("sadb_sup{\n");
while (len--) {
printf(" { id=%d ivlen=%d min=%d max=%d }\n",
alg->sadb_alg_id, alg->sadb_alg_ivlen,
alg->sadb_alg_minbits, alg->sadb_alg_maxbits);
alg++;
}
printf("}\n");
return;
}
static void
kdebug_sadb_lifetime(ext)
struct sadb_ext *ext;
{
struct sadb_lifetime *lft = (struct sadb_lifetime *)ext;
/* sanity check */
if (ext == NULL)
printf("kdebug_sadb_lifetime: NULL pointer was passed.\n");
printf("sadb_lifetime{ alloc=%u, bytes=%u\n",
lft->sadb_lifetime_allocations,
(u_int32_t)lft->sadb_lifetime_bytes);
printf(" addtime=%u, usetime=%u }\n",
(u_int32_t)lft->sadb_lifetime_addtime,
(u_int32_t)lft->sadb_lifetime_usetime);
return;
}
static void
kdebug_sadb_sa(ext)
struct sadb_ext *ext;
{
struct sadb_sa *sa = (struct sadb_sa *)ext;
/* sanity check */
if (ext == NULL)
panic("kdebug_sadb_sa: NULL pointer was passed.\n");
printf("sadb_sa{ spi=%u replay=%u state=%u\n",
(u_int32_t)ntohl(sa->sadb_sa_spi), sa->sadb_sa_replay,
sa->sadb_sa_state);
printf(" auth=%u encrypt=%u flags=0x%08x }\n",
sa->sadb_sa_auth, sa->sadb_sa_encrypt, sa->sadb_sa_flags);
return;
}
static void
kdebug_sadb_address(ext)
struct sadb_ext *ext;
{
struct sadb_address *addr = (struct sadb_address *)ext;
/* sanity check */
if (ext == NULL)
panic("kdebug_sadb_address: NULL pointer was passed.\n");
printf("sadb_address{ proto=%u prefixlen=%u reserved=0x%02x%02x }\n",
addr->sadb_address_proto, addr->sadb_address_prefixlen,
((u_char *)&addr->sadb_address_reserved)[0],
((u_char *)&addr->sadb_address_reserved)[1]);
kdebug_sockaddr((struct sockaddr *)((caddr_t)ext + sizeof(*addr)));
return;
}
static void
kdebug_sadb_key(ext)
struct sadb_ext *ext;
{
struct sadb_key *key = (struct sadb_key *)ext;
/* sanity check */
if (ext == NULL)
panic("kdebug_sadb_key: NULL pointer was passed.\n");
printf("sadb_key{ bits=%u reserved=%u\n",
key->sadb_key_bits, key->sadb_key_reserved);
printf(" key=");
/* sanity check 2 */
if ((key->sadb_key_bits >> 3) >
(PFKEY_UNUNIT64(key->sadb_key_len) - sizeof(struct sadb_key))) {
printf("kdebug_sadb_key: key length mismatch, bit:%d len:%ld.\n",
key->sadb_key_bits >> 3,
(long)PFKEY_UNUNIT64(key->sadb_key_len) - sizeof(struct sadb_key));
}
ipsec_hexdump((caddr_t)key + sizeof(struct sadb_key),
key->sadb_key_bits >> 3);
printf(" }\n");
return;
}
static void
kdebug_sadb_x_sa2(ext)
struct sadb_ext *ext;
{
struct sadb_x_sa2 *sa2 = (struct sadb_x_sa2 *)ext;
/* sanity check */
if (ext == NULL)
panic("kdebug_sadb_x_sa2: NULL pointer was passed.\n");
printf("sadb_x_sa2{ mode=%u reqid=%u\n",
sa2->sadb_x_sa2_mode, sa2->sadb_x_sa2_reqid);
printf(" reserved1=%u reserved2=%u sequence=%u }\n",
sa2->sadb_x_sa2_reserved1, sa2->sadb_x_sa2_reserved2,
sa2->sadb_x_sa2_sequence);
return;
}
void
kdebug_sadb_x_policy(ext)
struct sadb_ext *ext;
{
struct sadb_x_policy *xpl = (struct sadb_x_policy *)ext;
struct sockaddr *addr;
/* sanity check */
if (ext == NULL)
panic("kdebug_sadb_x_policy: NULL pointer was passed.\n");
#ifdef HAVE_PFKEY_POLICY_PRIORITY
printf("sadb_x_policy{ type=%u dir=%u id=%x priority=%u }\n",
#else
printf("sadb_x_policy{ type=%u dir=%u id=%x }\n",
#endif
xpl->sadb_x_policy_type, xpl->sadb_x_policy_dir,
#ifdef HAVE_PFKEY_POLICY_PRIORITY
xpl->sadb_x_policy_id, xpl->sadb_x_policy_priority);
#else
xpl->sadb_x_policy_id);
#endif
if (xpl->sadb_x_policy_type == IPSEC_POLICY_IPSEC) {
int tlen;
struct sadb_x_ipsecrequest *xisr;
tlen = PFKEY_UNUNIT64(xpl->sadb_x_policy_len) - sizeof(*xpl);
xisr = (struct sadb_x_ipsecrequest *)(xpl + 1);
while (tlen > 0) {
printf(" { len=%u proto=%u mode=%u level=%u reqid=%u\n",
xisr->sadb_x_ipsecrequest_len,
xisr->sadb_x_ipsecrequest_proto,
xisr->sadb_x_ipsecrequest_mode,
xisr->sadb_x_ipsecrequest_level,
xisr->sadb_x_ipsecrequest_reqid);
if (xisr->sadb_x_ipsecrequest_len > sizeof(*xisr)) {
addr = (struct sockaddr *)(xisr + 1);
kdebug_sockaddr(addr);
addr = (struct sockaddr *)((caddr_t)addr
+ sysdep_sa_len(addr));
kdebug_sockaddr(addr);
}
printf(" }\n");
/* prevent infinite loop */
if (xisr->sadb_x_ipsecrequest_len <= 0) {
printf("kdebug_sadb_x_policy: wrong policy struct.\n");
return;
}
/* prevent overflow */
if (xisr->sadb_x_ipsecrequest_len > tlen) {
printf("invalid ipsec policy length\n");
return;
}
tlen -= xisr->sadb_x_ipsecrequest_len;
xisr = (struct sadb_x_ipsecrequest *)((caddr_t)xisr
+ xisr->sadb_x_ipsecrequest_len);
}
if (tlen != 0)
panic("kdebug_sadb_x_policy: wrong policy struct.\n");
}
return;
}
#ifdef SADB_X_EXT_NAT_T_TYPE
static void
kdebug_sadb_x_nat_t_type(struct sadb_ext *ext)
{
struct sadb_x_nat_t_type *ntt = (struct sadb_x_nat_t_type *)ext;
/* sanity check */
if (ext == NULL)
panic("kdebug_sadb_x_nat_t_type: NULL pointer was passed.\n");
printf("sadb_x_nat_t_type{ type=%u }\n", ntt->sadb_x_nat_t_type_type);
return;
}
static void
kdebug_sadb_x_nat_t_port(struct sadb_ext *ext)
{
struct sadb_x_nat_t_port *ntp = (struct sadb_x_nat_t_port *)ext;
/* sanity check */
if (ext == NULL)
panic("kdebug_sadb_x_nat_t_port: NULL pointer was passed.\n");
printf("sadb_x_nat_t_port{ port=%u }\n", ntohs(ntp->sadb_x_nat_t_port_port));
return;
}
#endif
#ifdef _KERNEL
/* %%%: about SPD and SAD */
void
kdebug_secpolicy(sp)
struct secpolicy *sp;
{
/* sanity check */
if (sp == NULL)
panic("kdebug_secpolicy: NULL pointer was passed.\n");
printf("secpolicy{ refcnt=%u state=%u policy=%u\n",
sp->refcnt, sp->state, sp->policy);
kdebug_secpolicyindex(&sp->spidx);
switch (sp->policy) {
case IPSEC_POLICY_DISCARD:
printf(" type=discard }\n");
break;
case IPSEC_POLICY_NONE:
printf(" type=none }\n");
break;
case IPSEC_POLICY_IPSEC:
{
struct ipsecrequest *isr;
for (isr = sp->req; isr != NULL; isr = isr->next) {
printf(" level=%u\n", isr->level);
kdebug_secasindex(&isr->saidx);
if (isr->sav != NULL)
kdebug_secasv(isr->sav);
}
printf(" }\n");
}
break;
case IPSEC_POLICY_BYPASS:
printf(" type=bypass }\n");
break;
case IPSEC_POLICY_ENTRUST:
printf(" type=entrust }\n");
break;
default:
printf("kdebug_secpolicy: Invalid policy found. %d\n",
sp->policy);
break;
}
return;
}
void
kdebug_secpolicyindex(spidx)
struct secpolicyindex *spidx;
{
/* sanity check */
if (spidx == NULL)
panic("kdebug_secpolicyindex: NULL pointer was passed.\n");
printf("secpolicyindex{ dir=%u prefs=%u prefd=%u ul_proto=%u\n",
spidx->dir, spidx->prefs, spidx->prefd, spidx->ul_proto);
ipsec_hexdump((caddr_t)&spidx->src,
sysdep_sa_len((struct sockaddr *)&spidx->src));
printf("\n");
ipsec_hexdump((caddr_t)&spidx->dst,
sysdep_sa_len((struct sockaddr *)&spidx->dst));
printf("}\n");
return;
}
void
kdebug_secasindex(saidx)
struct secasindex *saidx;
{
/* sanity check */
if (saidx == NULL)
panic("kdebug_secpolicyindex: NULL pointer was passed.\n");
printf("secasindex{ mode=%u proto=%u\n",
saidx->mode, saidx->proto);
ipsec_hexdump((caddr_t)&saidx->src,
sysdep_sa_len((struct sockaddr *)&saidx->src));
printf("\n");
ipsec_hexdump((caddr_t)&saidx->dst,
sysdep_sa_len((struct sockaddr *)&saidx->dst));
printf("\n");
return;
}
void
kdebug_secasv(sav)
struct secasvar *sav;
{
/* sanity check */
if (sav == NULL)
panic("kdebug_secasv: NULL pointer was passed.\n");
printf("secas{");
kdebug_secasindex(&sav->sah->saidx);
printf(" refcnt=%u state=%u auth=%u enc=%u\n",
sav->refcnt, sav->state, sav->alg_auth, sav->alg_enc);
printf(" spi=%u flags=%u\n",
(u_int32_t)ntohl(sav->spi), sav->flags);
if (sav->key_auth != NULL)
kdebug_sadb_key((struct sadb_ext *)sav->key_auth);
if (sav->key_enc != NULL)
kdebug_sadb_key((struct sadb_ext *)sav->key_enc);
if (sav->iv != NULL) {
printf(" iv=");
ipsec_hexdump(sav->iv, sav->ivlen ? sav->ivlen : 8);
printf("\n");
}
if (sav->replay != NULL)
kdebug_secreplay(sav->replay);
if (sav->lft_c != NULL)
kdebug_sadb_lifetime((struct sadb_ext *)sav->lft_c);
if (sav->lft_h != NULL)
kdebug_sadb_lifetime((struct sadb_ext *)sav->lft_h);
if (sav->lft_s != NULL)
kdebug_sadb_lifetime((struct sadb_ext *)sav->lft_s);
#if notyet
/* XXX: misc[123] ? */
#endif
return;
}
static void
kdebug_secreplay(rpl)
struct secreplay *rpl;
{
int len, l;
/* sanity check */
if (rpl == NULL)
panic("kdebug_secreplay: NULL pointer was passed.\n");
printf(" secreplay{ count=%u wsize=%u seq=%u lastseq=%u",
rpl->count, rpl->wsize, rpl->seq, rpl->lastseq);
if (rpl->bitmap == NULL) {
printf(" }\n");
return;
}
printf("\n bitmap { ");
for (len = 0; len < rpl->wsize; len++) {
for (l = 7; l >= 0; l--)
printf("%u", (((rpl->bitmap)[len] >> l) & 1) ? 1 : 0);
}
printf(" }\n");
return;
}
void
kdebug_mbufhdr(m)
struct mbuf *m;
{
/* sanity check */
if (m == NULL)
return;
printf("mbuf(%p){ m_next:%p m_nextpkt:%p m_data:%p "
"m_len:%d m_type:0x%02x m_flags:0x%02x }\n",
m, m->m_next, m->m_nextpkt, m->m_data,
m->m_len, m->m_type, m->m_flags);
if (m->m_flags & M_PKTHDR) {
printf(" m_pkthdr{ len:%d rcvif:%p }\n",
m->m_pkthdr.len, m->m_pkthdr.rcvif);
}
#ifdef __FreeBSD__
if (m->m_flags & M_EXT) {
printf(" m_ext{ ext_buf:%p ext_free:%p "
"ext_size:%u ext_ref:%p }\n",
m->m_ext.ext_buf, m->m_ext.ext_free,
m->m_ext.ext_size, m->m_ext.ext_ref);
}
#endif
return;
}
void
kdebug_mbuf(m0)
struct mbuf *m0;
{
struct mbuf *m = m0;
int i, j;
for (j = 0; m; m = m->m_next) {
kdebug_mbufhdr(m);
printf(" m_data:\n");
for (i = 0; i < m->m_len; i++) {
if (i && i % 32 == 0)
printf("\n");
if (i % 4 == 0)
printf(" ");
printf("%02x", mtod(m, u_char *)[i]);
j++;
}
printf("\n");
}
return;
}
#endif /* _KERNEL */
static void
kdebug_sockaddr(addr)
struct sockaddr *addr;
{
struct sockaddr_in *sin4;
#ifdef INET6
struct sockaddr_in6 *sin6;
#endif
/* sanity check */
if (addr == NULL)
panic("kdebug_sockaddr: NULL pointer was passed.\n");
/* NOTE: We deal with port number as host byte order. */
printf("sockaddr{ len=%u family=%u", sysdep_sa_len(addr), addr->sa_family);
switch (addr->sa_family) {
case AF_INET:
sin4 = (struct sockaddr_in *)addr;
printf(" port=%u\n", ntohs(sin4->sin_port));
ipsec_hexdump((caddr_t)&sin4->sin_addr, sizeof(sin4->sin_addr));
break;
#ifdef INET6
case AF_INET6:
sin6 = (struct sockaddr_in6 *)addr;
printf(" port=%u\n", ntohs(sin6->sin6_port));
printf(" flowinfo=0x%08x, scope_id=0x%08x\n",
sin6->sin6_flowinfo, sin6->sin6_scope_id);
ipsec_hexdump((caddr_t)&sin6->sin6_addr,
sizeof(sin6->sin6_addr));
break;
#endif
}
printf(" }\n");
return;
}
void
ipsec_bindump(buf, len)
caddr_t buf;
int len;
{
int i;
for (i = 0; i < len; i++)
printf("%c", (unsigned char)buf[i]);
return;
}
void
ipsec_hexdump(buf, len)
caddr_t buf;
int len;
{
int i;
for (i = 0; i < len; i++) {
if (i != 0 && i % 32 == 0) printf("\n");
if (i % 4 == 0) printf(" ");
printf("%02x", (unsigned char)buf[i]);
}
#if 0
if (i % 32 != 0) printf("\n");
#endif
return;
}

View File

@ -0,0 +1,160 @@
/* $Id: libpfkey.h,v 1.1.1.1 2005/02/12 11:11:31 manu Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#ifndef _LIBPFKEY_H
#define _LIBPFKEY_H
#ifndef KAME_LIBPFKEY_H
#define KAME_LIBPFKEY_H
#define PRIORITY_LOW 0xC0000000
#define PRIORITY_DEFAULT 0x80000000
#define PRIORITY_HIGH 0x40000000
#define PRIORITY_OFFSET_POSITIVE_MAX 0x3fffffff
#define PRIORITY_OFFSET_NEGATIVE_MAX 0x40000000
struct sadb_msg;
extern void pfkey_sadump __P((struct sadb_msg *));
extern void pfkey_spdump __P((struct sadb_msg *));
struct sockaddr;
struct sadb_alg;
/* IPsec Library Routines */
int ipsec_check_keylen __P((u_int, u_int, u_int));
int ipsec_check_keylen2 __P((u_int, u_int, u_int));
int ipsec_get_keylen __P((u_int, u_int, struct sadb_alg *));
char *ipsec_dump_policy __P((caddr_t policy, char *delimiter));
void ipsec_hexdump __P((caddr_t buf, int len));
int ipsec_get_policylen __P((caddr_t policy));
caddr_t ipsec_set_policy __P((char *msg, int msglen));
const char *ipsec_strerror __P((void));
void kdebug_sadb __P((struct sadb_msg *base));
/* PFKey Routines */
u_int pfkey_set_softrate __P((u_int, u_int));
u_int pfkey_get_softrate __P((u_int));
int pfkey_send_getspi __P((int, u_int, u_int, struct sockaddr *,
struct sockaddr *, u_int32_t, u_int32_t, u_int32_t, u_int32_t));
int pfkey_send_update __P((int, u_int, u_int, struct sockaddr *,
struct sockaddr *, u_int32_t, u_int32_t, u_int,
caddr_t, u_int, u_int, u_int, u_int, u_int, u_int32_t, u_int64_t,
u_int64_t, u_int64_t, u_int32_t));
int pfkey_send_update_nat __P((int, u_int, u_int, struct sockaddr *,
struct sockaddr *, u_int32_t, u_int32_t, u_int,
caddr_t, u_int, u_int, u_int, u_int, u_int, u_int32_t, u_int64_t,
u_int64_t, u_int64_t, u_int32_t,
u_int8_t, u_int16_t, u_int16_t, struct sockaddr *, u_int16_t));
int pfkey_send_add __P((int, u_int, u_int, struct sockaddr *,
struct sockaddr *, u_int32_t, u_int32_t, u_int,
caddr_t, u_int, u_int, u_int, u_int, u_int, u_int32_t, u_int64_t,
u_int64_t, u_int64_t, u_int32_t));
int pfkey_send_add_nat __P((int, u_int, u_int, struct sockaddr *,
struct sockaddr *, u_int32_t, u_int32_t, u_int,
caddr_t, u_int, u_int, u_int, u_int, u_int, u_int32_t, u_int64_t,
u_int64_t, u_int64_t, u_int32_t,
u_int8_t, u_int16_t, u_int16_t, struct sockaddr *, u_int16_t));
int pfkey_send_delete __P((int, u_int, u_int,
struct sockaddr *, struct sockaddr *, u_int32_t));
int pfkey_send_delete_all __P((int, u_int, u_int,
struct sockaddr *, struct sockaddr *));
int pfkey_send_get __P((int, u_int, u_int,
struct sockaddr *, struct sockaddr *, u_int32_t));
int pfkey_send_register __P((int, u_int));
int pfkey_recv_register __P((int));
int pfkey_set_supported __P((struct sadb_msg *, int));
int pfkey_send_flush __P((int, u_int));
int pfkey_send_dump __P((int, u_int));
int pfkey_send_promisc_toggle __P((int, int));
int pfkey_send_spdadd __P((int, struct sockaddr *, u_int,
struct sockaddr *, u_int, u_int, caddr_t, int, u_int32_t));
int pfkey_send_spdadd2 __P((int, struct sockaddr *, u_int,
struct sockaddr *, u_int, u_int, u_int64_t, u_int64_t,
caddr_t, int, u_int32_t));
int pfkey_send_spdupdate __P((int, struct sockaddr *, u_int,
struct sockaddr *, u_int, u_int, caddr_t, int, u_int32_t));
int pfkey_send_spdupdate2 __P((int, struct sockaddr *, u_int,
struct sockaddr *, u_int, u_int, u_int64_t, u_int64_t,
caddr_t, int, u_int32_t));
int pfkey_send_spddelete __P((int, struct sockaddr *, u_int,
struct sockaddr *, u_int, u_int, caddr_t, int, u_int32_t));
int pfkey_send_spddelete2 __P((int, u_int32_t));
int pfkey_send_spdget __P((int, u_int32_t));
int pfkey_send_spdsetidx __P((int, struct sockaddr *, u_int,
struct sockaddr *, u_int, u_int, caddr_t, int, u_int32_t));
int pfkey_send_spdflush __P((int));
int pfkey_send_spddump __P((int));
int pfkey_open __P((void));
void pfkey_close __P((int));
struct sadb_msg *pfkey_recv __P((int));
int pfkey_send __P((int, struct sadb_msg *, int));
int pfkey_align __P((struct sadb_msg *, caddr_t *));
int pfkey_check __P((caddr_t *));
#ifndef __SYSDEP_SA_LEN__
#define __SYSDEP_SA_LEN__
#include <netinet/in.h>
#ifndef IPPROTO_IPV4
#define IPPROTO_IPV4 IPPROTO_IPIP
#endif
#ifndef IPPROTO_IPCOMP
#define IPPROTO_IPCOMP IPPROTO_COMP
#endif
static inline u_int8_t
sysdep_sa_len (const struct sockaddr *sa)
{
#ifdef __linux__
switch (sa->sa_family)
{
case AF_INET:
return sizeof (struct sockaddr_in);
case AF_INET6:
return sizeof (struct sockaddr_in6);
}
// log_print ("sysdep_sa_len: unknown sa family %d", sa->sa_family);
return sizeof (struct sockaddr_in);
#else
return sa->sa_len;
#endif
}
#endif
#endif /* KAME_LIBPFKEY_H */
#endif /* _LIBPFKEY_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,694 @@
/* $KAME: pfkey_dump.c,v 1.45 2003/09/08 10:14:56 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#ifdef HAVE_NETINET6_IPSEC
# include <netinet6/ipsec.h>
#else
# include <netinet/ipsec.h>
#endif
#include <net/pfkeyv2.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <netdb.h>
#include "ipsec_strerror.h"
#include "libpfkey.h"
/* cope with old kame headers - ugly */
#ifndef SADB_X_AALG_MD5
#define SADB_X_AALG_MD5 SADB_AALG_MD5
#endif
#ifndef SADB_X_AALG_SHA
#define SADB_X_AALG_SHA SADB_AALG_SHA
#endif
#ifndef SADB_X_AALG_NULL
#define SADB_X_AALG_NULL SADB_AALG_NULL
#endif
#ifndef SADB_X_EALG_BLOWFISHCBC
#define SADB_X_EALG_BLOWFISHCBC SADB_EALG_BLOWFISHCBC
#endif
#ifndef SADB_X_EALG_CAST128CBC
#define SADB_X_EALG_CAST128CBC SADB_EALG_CAST128CBC
#endif
#ifndef SADB_X_EALG_RC5CBC
#ifdef SADB_EALG_RC5CBC
#define SADB_X_EALG_RC5CBC SADB_EALG_RC5CBC
#endif
#endif
#define GETMSGSTR(str, num) \
do { \
if (sizeof((str)[0]) == 0 \
|| num >= sizeof(str)/sizeof((str)[0])) \
printf("%u ", (num)); \
else if (strlen((str)[(num)]) == 0) \
printf("%u ", (num)); \
else \
printf("%s ", (str)[(num)]); \
} while (0)
#define GETMSGV2S(v2s, num) \
do { \
struct val2str *p; \
for (p = (v2s); p && p->str; p++) { \
if (p->val == (num)) \
break; \
} \
if (p && p->str) \
printf("%s ", p->str); \
else \
printf("%u ", (num)); \
} while (0)
static char *str_ipaddr __P((struct sockaddr *));
static char *str_prefport __P((u_int, u_int, u_int, u_int));
static void str_upperspec __P((u_int, u_int, u_int));
static char *str_time __P((time_t));
static void str_lifetime_byte __P((struct sadb_lifetime *, char *));
struct val2str {
int val;
const char *str;
};
/*
* Must to be re-written about following strings.
*/
static char *str_satype[] = {
"unspec",
"unknown",
"ah",
"esp",
"unknown",
"rsvp",
"ospfv2",
"ripv2",
"mip",
"ipcomp",
};
static char *str_mode[] = {
"any",
"transport",
"tunnel",
};
static char *str_state[] = {
"larval",
"mature",
"dying",
"dead",
};
static struct val2str str_alg_auth[] = {
{ SADB_AALG_NONE, "none", },
{ SADB_AALG_MD5HMAC, "hmac-md5", },
{ SADB_AALG_SHA1HMAC, "hmac-sha1", },
{ SADB_X_AALG_MD5, "md5", },
{ SADB_X_AALG_SHA, "sha", },
{ SADB_X_AALG_NULL, "null", },
#ifdef SADB_X_AALG_SHA2_256
{ SADB_X_AALG_SHA2_256, "hmac-sha2-256", },
#endif
#ifdef SADB_X_AALG_SHA2_384
{ SADB_X_AALG_SHA2_384, "hmac-sha2-384", },
#endif
#ifdef SADB_X_AALG_SHA2_512
{ SADB_X_AALG_SHA2_512, "hmac-sha2-512", },
#endif
#ifdef SADB_X_AALG_RIPEMD160HMAC
{ SADB_X_AALG_RIPEMD160HMAC, "hmac-ripemd160", },
#endif
#ifdef SADB_X_AALG_AES_XCBC_MAC
{ SADB_X_AALG_AES_XCBC_MAC, "aes-xcbc-mac", },
#endif
{ -1, NULL, },
};
static struct val2str str_alg_enc[] = {
{ SADB_EALG_NONE, "none", },
{ SADB_EALG_DESCBC, "des-cbc", },
{ SADB_EALG_3DESCBC, "3des-cbc", },
{ SADB_EALG_NULL, "null", },
#ifdef SADB_X_EALG_RC5CBC
{ SADB_X_EALG_RC5CBC, "rc5-cbc", },
#endif
{ SADB_X_EALG_CAST128CBC, "cast128-cbc", },
{ SADB_X_EALG_BLOWFISHCBC, "blowfish-cbc", },
#ifdef SADB_X_EALG_AESCBC
{ SADB_X_EALG_AESCBC, "aes-cbc", },
#endif
#ifdef SADB_X_EALG_TWOFISHCBC
{ SADB_X_EALG_TWOFISHCBC, "twofish-cbc", },
#endif
#ifdef SADB_X_EALG_AESCTR
{ SADB_X_EALG_AESCTR, "aes-ctr", },
#endif
{ -1, NULL, },
};
static struct val2str str_alg_comp[] = {
{ SADB_X_CALG_NONE, "none", },
{ SADB_X_CALG_OUI, "oui", },
{ SADB_X_CALG_DEFLATE, "deflate", },
{ SADB_X_CALG_LZS, "lzs", },
{ -1, NULL, },
};
/*
* dump SADB_MSG formated. For debugging, you should use kdebug_sadb().
*/
void
pfkey_sadump(m)
struct sadb_msg *m;
{
caddr_t mhp[SADB_EXT_MAX + 1];
struct sadb_sa *m_sa;
struct sadb_x_sa2 *m_sa2;
struct sadb_lifetime *m_lftc, *m_lfth, *m_lfts;
struct sadb_address *m_saddr, *m_daddr, *m_paddr;
struct sadb_key *m_auth, *m_enc;
struct sadb_ident *m_sid, *m_did;
struct sadb_sens *m_sens;
#ifdef SADB_X_EXT_NAT_T_TYPE
struct sadb_x_nat_t_type *natt_type;
struct sadb_x_nat_t_port *natt_sport, *natt_dport;
struct sadb_address *natt_oa;
int use_natt = 0;
#endif
/* check pfkey message. */
if (pfkey_align(m, mhp)) {
printf("%s\n", ipsec_strerror());
return;
}
if (pfkey_check(mhp)) {
printf("%s\n", ipsec_strerror());
return;
}
m_sa = (struct sadb_sa *)mhp[SADB_EXT_SA];
m_sa2 = (struct sadb_x_sa2 *)mhp[SADB_X_EXT_SA2];
m_lftc = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_CURRENT];
m_lfth = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_HARD];
m_lfts = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_SOFT];
m_saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
m_daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
m_paddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_PROXY];
m_auth = (struct sadb_key *)mhp[SADB_EXT_KEY_AUTH];
m_enc = (struct sadb_key *)mhp[SADB_EXT_KEY_ENCRYPT];
m_sid = (struct sadb_ident *)mhp[SADB_EXT_IDENTITY_SRC];
m_did = (struct sadb_ident *)mhp[SADB_EXT_IDENTITY_DST];
m_sens = (struct sadb_sens *)mhp[SADB_EXT_SENSITIVITY];
#ifdef SADB_X_EXT_NAT_T_TYPE
natt_type = (struct sadb_x_nat_t_type *)mhp[SADB_X_EXT_NAT_T_TYPE];
natt_sport = (struct sadb_x_nat_t_port *)mhp[SADB_X_EXT_NAT_T_SPORT];
natt_dport = (struct sadb_x_nat_t_port *)mhp[SADB_X_EXT_NAT_T_DPORT];
natt_oa = (struct sadb_address *)mhp[SADB_X_EXT_NAT_T_OA];
if (natt_type && natt_type->sadb_x_nat_t_type_type)
use_natt = 1;
#endif
/* source address */
if (m_saddr == NULL) {
printf("no ADDRESS_SRC extension.\n");
return;
}
printf("%s", str_ipaddr((struct sockaddr *)(m_saddr + 1)));
#ifdef SADB_X_EXT_NAT_T_TYPE
if (use_natt && natt_sport)
printf("[%u]", ntohs(natt_sport->sadb_x_nat_t_port_port));
#endif
printf(" ");
/* destination address */
if (m_daddr == NULL) {
printf(" no ADDRESS_DST extension.\n");
return;
}
printf("%s", str_ipaddr((struct sockaddr *)(m_daddr + 1)));
#ifdef SADB_X_EXT_NAT_T_TYPE
if (use_natt && natt_dport)
printf("[%u]", ntohs(natt_dport->sadb_x_nat_t_port_port));
#endif
printf(" ");
/* SA type */
if (m_sa == NULL) {
printf("no SA extension.\n");
return;
}
if (m_sa2 == NULL) {
printf("no SA2 extension.\n");
return;
}
printf("\n\t");
#ifdef SADB_X_EXT_NAT_T_TYPE
if (use_natt && m->sadb_msg_satype == SADB_SATYPE_ESP)
printf("esp-udp ");
else if (use_natt)
printf("natt+");
if (!use_natt || m->sadb_msg_satype != SADB_SATYPE_ESP)
#endif
GETMSGSTR(str_satype, m->sadb_msg_satype);
printf("mode=");
GETMSGSTR(str_mode, m_sa2->sadb_x_sa2_mode);
printf("spi=%u(0x%08x) reqid=%u(0x%08x)\n",
(u_int32_t)ntohl(m_sa->sadb_sa_spi),
(u_int32_t)ntohl(m_sa->sadb_sa_spi),
(u_int32_t)m_sa2->sadb_x_sa2_reqid,
(u_int32_t)m_sa2->sadb_x_sa2_reqid);
#ifdef SADB_X_EXT_NAT_T_TYPE
/* other NAT-T information */
if (use_natt && natt_oa)
printf("\tNAT OA=%s\n",
str_ipaddr((struct sockaddr *)(natt_oa + 1)));
#endif
/* encryption key */
if (m->sadb_msg_satype == SADB_X_SATYPE_IPCOMP) {
printf("\tC: ");
GETMSGV2S(str_alg_comp, m_sa->sadb_sa_encrypt);
} else if (m->sadb_msg_satype == SADB_SATYPE_ESP) {
if (m_enc != NULL) {
printf("\tE: ");
GETMSGV2S(str_alg_enc, m_sa->sadb_sa_encrypt);
ipsec_hexdump((caddr_t)m_enc + sizeof(*m_enc),
m_enc->sadb_key_bits / 8);
printf("\n");
}
}
/* authentication key */
if (m_auth != NULL) {
printf("\tA: ");
GETMSGV2S(str_alg_auth, m_sa->sadb_sa_auth);
ipsec_hexdump((caddr_t)m_auth + sizeof(*m_auth),
m_auth->sadb_key_bits / 8);
printf("\n");
}
/* replay windoe size & flags */
printf("\tseq=0x%08x replay=%u flags=0x%08x ",
m_sa2->sadb_x_sa2_sequence,
m_sa->sadb_sa_replay,
m_sa->sadb_sa_flags);
/* state */
printf("state=");
GETMSGSTR(str_state, m_sa->sadb_sa_state);
printf("\n");
/* lifetime */
if (m_lftc != NULL) {
time_t tmp_time = time(0);
printf("\tcreated: %s",
str_time(m_lftc->sadb_lifetime_addtime));
printf("\tcurrent: %s\n", str_time(tmp_time));
printf("\tdiff: %lu(s)",
(u_long)(m_lftc->sadb_lifetime_addtime == 0 ?
0 : (tmp_time - m_lftc->sadb_lifetime_addtime)));
printf("\thard: %lu(s)",
(u_long)(m_lfth == NULL ?
0 : m_lfth->sadb_lifetime_addtime));
printf("\tsoft: %lu(s)\n",
(u_long)(m_lfts == NULL ?
0 : m_lfts->sadb_lifetime_addtime));
printf("\tlast: %s",
str_time(m_lftc->sadb_lifetime_usetime));
printf("\thard: %lu(s)",
(u_long)(m_lfth == NULL ?
0 : m_lfth->sadb_lifetime_usetime));
printf("\tsoft: %lu(s)\n",
(u_long)(m_lfts == NULL ?
0 : m_lfts->sadb_lifetime_usetime));
str_lifetime_byte(m_lftc, "current");
str_lifetime_byte(m_lfth, "hard");
str_lifetime_byte(m_lfts, "soft");
printf("\n");
printf("\tallocated: %lu",
(unsigned long)m_lftc->sadb_lifetime_allocations);
printf("\thard: %lu",
(u_long)(m_lfth == NULL ?
0 : m_lfth->sadb_lifetime_allocations));
printf("\tsoft: %lu\n",
(u_long)(m_lfts == NULL ?
0 : m_lfts->sadb_lifetime_allocations));
}
printf("\tsadb_seq=%lu pid=%lu ",
(u_long)m->sadb_msg_seq,
(u_long)m->sadb_msg_pid);
/* XXX DEBUG */
printf("refcnt=%u\n", m->sadb_msg_reserved);
return;
}
void
pfkey_spdump(m)
struct sadb_msg *m;
{
char pbuf[NI_MAXSERV];
caddr_t mhp[SADB_EXT_MAX + 1];
struct sadb_address *m_saddr, *m_daddr;
#ifdef SADB_X_EXT_TAG
struct sadb_x_tag *m_tag;
#endif
struct sadb_x_policy *m_xpl;
struct sadb_lifetime *m_lftc = NULL, *m_lfth = NULL;
struct sockaddr *sa;
u_int16_t sport = 0, dport = 0;
/* check pfkey message. */
if (pfkey_align(m, mhp)) {
printf("%s\n", ipsec_strerror());
return;
}
if (pfkey_check(mhp)) {
printf("%s\n", ipsec_strerror());
return;
}
m_saddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_SRC];
m_daddr = (struct sadb_address *)mhp[SADB_EXT_ADDRESS_DST];
#ifdef SADB_X_EXT_TAG
m_tag = (struct sadb_x_tag *)mhp[SADB_X_EXT_TAG];
#endif
m_xpl = (struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY];
m_lftc = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_CURRENT];
m_lfth = (struct sadb_lifetime *)mhp[SADB_EXT_LIFETIME_HARD];
#ifdef __linux__
/* *bsd indicates per-socket policies by omiting src and dst
* extensions. Linux always includes them, but we can catch it
* by checkin for policy id.
*/
if (m_xpl->sadb_x_policy_id % 8 >= 3) {
printf("(per-socket policy) ");
} else
#endif
if (m_saddr && m_daddr) {
/* source address */
sa = (struct sockaddr *)(m_saddr + 1);
switch (sa->sa_family) {
case AF_INET:
case AF_INET6:
if (getnameinfo(sa, sysdep_sa_len(sa), NULL, 0,
pbuf, sizeof(pbuf), NI_NUMERICSERV) != 0)
sport = 0; /*XXX*/
else
sport = atoi(pbuf);
printf("%s%s ", str_ipaddr(sa),
str_prefport(sa->sa_family,
m_saddr->sadb_address_prefixlen, sport,
m_saddr->sadb_address_proto));
break;
default:
printf("unknown-af ");
break;
}
/* destination address */
sa = (struct sockaddr *)(m_daddr + 1);
switch (sa->sa_family) {
case AF_INET:
case AF_INET6:
if (getnameinfo(sa, sysdep_sa_len(sa), NULL, 0,
pbuf, sizeof(pbuf), NI_NUMERICSERV) != 0)
dport = 0; /*XXX*/
else
dport = atoi(pbuf);
printf("%s%s ", str_ipaddr(sa),
str_prefport(sa->sa_family,
m_daddr->sadb_address_prefixlen, dport,
m_saddr->sadb_address_proto));
break;
default:
printf("unknown-af ");
break;
}
/* upper layer protocol */
if (m_saddr->sadb_address_proto !=
m_daddr->sadb_address_proto) {
printf("upper layer protocol mismatched.\n");
return;
}
str_upperspec(m_saddr->sadb_address_proto, sport, dport);
}
#ifdef SADB_X_EXT_TAG
else if (m_tag)
printf("tagged \"%s\" ", m_tag->sadb_x_tag_name);
#endif
else
printf("(no selector, probably per-socket policy) ");
/* policy */
{
char *d_xpl;
if (m_xpl == NULL) {
printf("no X_POLICY extension.\n");
return;
}
d_xpl = ipsec_dump_policy((char *)m_xpl, "\n\t");
if (!d_xpl)
printf("\n\tPolicy:[%s]\n", ipsec_strerror());
else {
/* dump SPD */
printf("\n\t%s\n", d_xpl);
free(d_xpl);
}
}
/* lifetime */
if (m_lftc) {
printf("\tcreated: %s ",
str_time(m_lftc->sadb_lifetime_addtime));
printf("lastused: %s\n",
str_time(m_lftc->sadb_lifetime_usetime));
}
if (m_lfth) {
printf("\tlifetime: %lu(s) ",
(u_long)m_lfth->sadb_lifetime_addtime);
printf("validtime: %lu(s)\n",
(u_long)m_lfth->sadb_lifetime_usetime);
}
printf("\tspid=%ld seq=%ld pid=%ld\n",
(u_long)m_xpl->sadb_x_policy_id,
(u_long)m->sadb_msg_seq,
(u_long)m->sadb_msg_pid);
/* XXX TEST */
printf("\trefcnt=%u\n", m->sadb_msg_reserved);
return;
}
/*
* set "ipaddress" to buffer.
*/
static char *
str_ipaddr(sa)
struct sockaddr *sa;
{
static char buf[NI_MAXHOST];
const int niflag = NI_NUMERICHOST;
if (sa == NULL)
return "";
if (getnameinfo(sa, sysdep_sa_len(sa), buf, sizeof(buf), NULL, 0, niflag) == 0)
return buf;
return NULL;
}
/*
* set "/prefix[port number]" to buffer.
*/
static char *
str_prefport(family, pref, port, ulp)
u_int family, pref, port, ulp;
{
static char buf[128];
char prefbuf[128];
char portbuf[128];
int plen;
switch (family) {
case AF_INET:
plen = sizeof(struct in_addr) << 3;
break;
case AF_INET6:
plen = sizeof(struct in6_addr) << 3;
break;
default:
return "?";
}
if (pref == plen)
prefbuf[0] = '\0';
else
snprintf(prefbuf, sizeof(prefbuf), "/%u", pref);
if (ulp == IPPROTO_ICMPV6)
memset(portbuf, 0, sizeof(portbuf));
else {
if (port == IPSEC_PORT_ANY)
snprintf(portbuf, sizeof(portbuf), "[%s]", "any");
else
snprintf(portbuf, sizeof(portbuf), "[%u]", port);
}
snprintf(buf, sizeof(buf), "%s%s", prefbuf, portbuf);
return buf;
}
static void
str_upperspec(ulp, p1, p2)
u_int ulp, p1, p2;
{
if (ulp == IPSEC_ULPROTO_ANY)
printf("any");
else if (ulp == IPPROTO_ICMPV6) {
printf("icmp6");
if (!(p1 == IPSEC_PORT_ANY && p2 == IPSEC_PORT_ANY))
printf(" %u,%u", p1, p2);
} else {
struct protoent *ent;
switch (ulp) {
case IPPROTO_IPV4:
printf("ip4");
break;
default:
ent = getprotobynumber(ulp);
if (ent)
printf("%s", ent->p_name);
else
printf("%u", ulp);
endprotoent();
break;
}
}
}
/*
* set "Mon Day Time Year" to buffer
*/
static char *
str_time(t)
time_t t;
{
static char buf[128];
if (t == 0) {
int i = 0;
for (;i < 20;) buf[i++] = ' ';
} else {
char *t0;
t0 = ctime(&t);
memcpy(buf, t0 + 4, 20);
}
buf[20] = '\0';
return(buf);
}
static void
str_lifetime_byte(x, str)
struct sadb_lifetime *x;
char *str;
{
double y;
char *unit;
int w;
if (x == NULL) {
printf("\t%s: 0(bytes)", str);
return;
}
#if 0
if ((x->sadb_lifetime_bytes) / 1024 / 1024) {
y = (x->sadb_lifetime_bytes) * 1.0 / 1024 / 1024;
unit = "M";
w = 1;
} else if ((x->sadb_lifetime_bytes) / 1024) {
y = (x->sadb_lifetime_bytes) * 1.0 / 1024;
unit = "K";
w = 1;
} else {
y = (x->sadb_lifetime_bytes) * 1.0;
unit = "";
w = 0;
}
#else
y = (x->sadb_lifetime_bytes) * 1.0;
unit = "";
w = 0;
#endif
printf("\t%s: %.*f(%sbytes)", str, w, y, unit);
}

View File

@ -0,0 +1,614 @@
/* $KAME: policy_parse.y,v 1.21 2003/12/12 08:01:26 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
/*
* IN/OUT bound policy configuration take place such below:
* in <priority> <policy>
* out <priority> <policy>
*
* <priority> is one of the following:
* priority <signed int> where the integer is an offset from the default
* priority, where negative numbers indicate lower
* priority (towards end of list) and positive numbers
* indicate higher priority (towards beginning of list)
*
* priority {low,def,high} {+,-} <unsigned int> where low and high are
* constants which are closer
* to the end of the list and
* beginning of the list,
* respectively
*
* <policy> is one of following:
* "discard", "none", "ipsec <requests>", "entrust", "bypass",
*
* The following requests are accepted as <requests>:
*
* protocol/mode/src-dst/level
* protocol/mode/src-dst parsed as protocol/mode/src-dst/default
* protocol/mode/src-dst/ parsed as protocol/mode/src-dst/default
* protocol/transport parsed as protocol/mode/any-any/default
* protocol/transport//level parsed as protocol/mode/any-any/level
*
* You can concatenate these requests with either ' '(single space) or '\n'.
*/
%{
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <netinet/in.h>
#ifdef HAVE_NETINET6_IPSEC
# include <netinet6/ipsec.h>
#else
# include <netinet/ipsec.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <netdb.h>
#include <errno.h>
#include "config.h"
#include "ipsec_strerror.h"
#include "libpfkey.h"
#ifndef INT32_MAX
#define INT32_MAX (0xffffffff)
#endif
#ifndef INT32_MIN
#define INT32_MIN (-INT32_MAX-1)
#endif
#define ATOX(c) \
(isdigit(c) ? (c - '0') : (isupper(c) ? (c - 'A' + 10) : (c - 'a' + 10) ))
static u_int8_t *pbuf = NULL; /* sadb_x_policy buffer */
static int tlen = 0; /* total length of pbuf */
static int offset = 0; /* offset of pbuf */
static int p_dir, p_type, p_protocol, p_mode, p_level, p_reqid;
static u_int32_t p_priority = 0;
static long p_priority_offset = 0;
static struct sockaddr *p_src = NULL;
static struct sockaddr *p_dst = NULL;
struct _val;
extern void yyerror __P((char *msg));
static struct sockaddr *parse_sockaddr __P((struct _val *buf));
static int rule_check __P((void));
static int init_x_policy __P((void));
static int set_x_request __P((struct sockaddr *src, struct sockaddr *dst));
static int set_sockaddr __P((struct sockaddr *addr));
static void policy_parse_request_init __P((void));
static caddr_t policy_parse __P((char *msg, int msglen));
extern void __policy__strbuffer__init__ __P((char *msg));
extern void __policy__strbuffer__free__ __P((void));
extern int yyparse __P((void));
extern int yylex __P((void));
extern char *__libipsectext; /*XXX*/
%}
%union {
u_int num;
u_int32_t num32;
struct _val {
int len;
char *buf;
} val;
}
%token DIR
%token PRIORITY PLUS
%token <num32> PRIO_BASE
%token <val> PRIO_OFFSET
%token ACTION PROTOCOL MODE LEVEL LEVEL_SPECIFY IPADDRESS
%token ME ANY
%token SLASH HYPHEN
%type <num> DIR PRIORITY ACTION PROTOCOL MODE LEVEL
%type <val> IPADDRESS LEVEL_SPECIFY
%%
policy_spec
: DIR ACTION
{
p_dir = $1;
p_type = $2;
#ifdef HAVE_PFKEY_POLICY_PRIORITY
p_priority = PRIORITY_DEFAULT;
#else
p_priority = 0;
#endif
if (init_x_policy())
return -1;
}
rules
| DIR PRIORITY PRIO_OFFSET ACTION
{
char *offset_buf;
p_dir = $1;
p_type = $4;
/* buffer big enough to hold a prepended negative sign */
offset_buf = malloc($3.len + 2);
if (offset_buf == NULL)
{
__ipsec_errcode = EIPSEC_NO_BUFS;
return -1;
}
/* positive input value means higher priority, therefore lower
actual value so that is closer to the beginning of the list */
sprintf (offset_buf, "-%s", $3.buf);
errno = 0;
p_priority_offset = atol(offset_buf);
free(offset_buf);
if (errno != 0 || p_priority_offset < INT32_MIN)
{
__ipsec_errcode = EIPSEC_INVAL_PRIORITY_OFFSET;
return -1;
}
p_priority = PRIORITY_DEFAULT + (u_int32_t) p_priority_offset;
if (init_x_policy())
return -1;
}
rules
| DIR PRIORITY HYPHEN PRIO_OFFSET ACTION
{
p_dir = $1;
p_type = $5;
errno = 0;
p_priority_offset = atol($4.buf);
if (errno != 0 || p_priority_offset > INT32_MAX)
{
__ipsec_errcode = EIPSEC_INVAL_PRIORITY_OFFSET;
return -1;
}
/* negative input value means lower priority, therefore higher
actual value so that is closer to the end of the list */
p_priority = PRIORITY_DEFAULT + (u_int32_t) p_priority_offset;
if (init_x_policy())
return -1;
}
rules
| DIR PRIORITY PRIO_BASE ACTION
{
p_dir = $1;
p_type = $4;
p_priority = $3;
if (init_x_policy())
return -1;
}
rules
| DIR PRIORITY PRIO_BASE PLUS PRIO_OFFSET ACTION
{
p_dir = $1;
p_type = $6;
errno = 0;
p_priority_offset = atol($5.buf);
if (errno != 0 || p_priority_offset > PRIORITY_OFFSET_NEGATIVE_MAX)
{
__ipsec_errcode = EIPSEC_INVAL_PRIORITY_BASE_OFFSET;
return -1;
}
/* adding value means higher priority, therefore lower
actual value so that is closer to the beginning of the list */
p_priority = $3 - (u_int32_t) p_priority_offset;
if (init_x_policy())
return -1;
}
rules
| DIR PRIORITY PRIO_BASE HYPHEN PRIO_OFFSET ACTION
{
p_dir = $1;
p_type = $6;
errno = 0;
p_priority_offset = atol($5.buf);
if (errno != 0 || p_priority_offset > PRIORITY_OFFSET_POSITIVE_MAX)
{
__ipsec_errcode = EIPSEC_INVAL_PRIORITY_BASE_OFFSET;
return -1;
}
/* subtracting value means lower priority, therefore higher
actual value so that is closer to the end of the list */
p_priority = $3 + (u_int32_t) p_priority_offset;
if (init_x_policy())
return -1;
}
rules
| DIR
{
p_dir = $1;
p_type = 0; /* ignored it by kernel */
p_priority = 0;
if (init_x_policy())
return -1;
}
;
rules
: /*NOTHING*/
| rules rule {
if (rule_check() < 0)
return -1;
if (set_x_request(p_src, p_dst) < 0)
return -1;
policy_parse_request_init();
}
;
rule
: protocol SLASH mode SLASH addresses SLASH level
| protocol SLASH mode SLASH addresses SLASH
| protocol SLASH mode SLASH addresses
| protocol SLASH mode SLASH
| protocol SLASH mode SLASH SLASH level
| protocol SLASH mode
| protocol SLASH {
__ipsec_errcode = EIPSEC_FEW_ARGUMENTS;
return -1;
}
| protocol {
__ipsec_errcode = EIPSEC_FEW_ARGUMENTS;
return -1;
}
;
protocol
: PROTOCOL { p_protocol = $1; }
;
mode
: MODE { p_mode = $1; }
;
level
: LEVEL {
p_level = $1;
p_reqid = 0;
}
| LEVEL_SPECIFY {
p_level = IPSEC_LEVEL_UNIQUE;
p_reqid = atol($1.buf); /* atol() is good. */
}
;
addresses
: IPADDRESS {
p_src = parse_sockaddr(&$1);
if (p_src == NULL)
return -1;
}
HYPHEN
IPADDRESS {
p_dst = parse_sockaddr(&$4);
if (p_dst == NULL)
return -1;
}
| ME HYPHEN ANY {
if (p_dir != IPSEC_DIR_OUTBOUND) {
__ipsec_errcode = EIPSEC_INVAL_DIR;
return -1;
}
}
| ANY HYPHEN ME {
if (p_dir != IPSEC_DIR_INBOUND) {
__ipsec_errcode = EIPSEC_INVAL_DIR;
return -1;
}
}
/*
| ME HYPHEN ME
*/
;
%%
void
yyerror(msg)
char *msg;
{
fprintf(stderr, "libipsec: %s while parsing \"%s\"\n",
msg, __libipsectext);
return;
}
static struct sockaddr *
parse_sockaddr(buf)
struct _val *buf;
{
struct addrinfo hints, *res;
char *serv = NULL;
int error;
struct sockaddr *newaddr = NULL;
memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_UNSPEC;
hints.ai_flags = AI_NUMERICHOST;
error = getaddrinfo(buf->buf, serv, &hints, &res);
if (error != 0) {
yyerror("invalid IP address");
__ipsec_set_strerror(gai_strerror(error));
return NULL;
}
if (res->ai_addr == NULL) {
yyerror("invalid IP address");
__ipsec_set_strerror(gai_strerror(error));
return NULL;
}
newaddr = malloc(res->ai_addrlen);
if (newaddr == NULL) {
__ipsec_errcode = EIPSEC_NO_BUFS;
freeaddrinfo(res);
return NULL;
}
memcpy(newaddr, res->ai_addr, res->ai_addrlen);
freeaddrinfo(res);
__ipsec_errcode = EIPSEC_NO_ERROR;
return newaddr;
}
static int
rule_check()
{
if (p_type == IPSEC_POLICY_IPSEC) {
if (p_protocol == IPPROTO_IP) {
__ipsec_errcode = EIPSEC_NO_PROTO;
return -1;
}
if (p_mode != IPSEC_MODE_TRANSPORT
&& p_mode != IPSEC_MODE_TUNNEL) {
__ipsec_errcode = EIPSEC_INVAL_MODE;
return -1;
}
if (p_src == NULL && p_dst == NULL) {
if (p_mode != IPSEC_MODE_TRANSPORT) {
__ipsec_errcode = EIPSEC_INVAL_ADDRESS;
return -1;
}
}
else if (p_src->sa_family != p_dst->sa_family) {
__ipsec_errcode = EIPSEC_FAMILY_MISMATCH;
return -1;
}
}
__ipsec_errcode = EIPSEC_NO_ERROR;
return 0;
}
static int
init_x_policy()
{
struct sadb_x_policy *p;
if (pbuf) {
free(pbuf);
tlen = 0;
}
pbuf = malloc(sizeof(struct sadb_x_policy));
if (pbuf == NULL) {
__ipsec_errcode = EIPSEC_NO_BUFS;
return -1;
}
tlen = sizeof(struct sadb_x_policy);
memset(pbuf, 0, tlen);
p = (struct sadb_x_policy *)pbuf;
p->sadb_x_policy_len = 0; /* must update later */
p->sadb_x_policy_exttype = SADB_X_EXT_POLICY;
p->sadb_x_policy_type = p_type;
p->sadb_x_policy_dir = p_dir;
p->sadb_x_policy_id = 0;
#ifdef HAVE_PFKEY_POLICY_PRIORITY
p->sadb_x_policy_priority = p_priority;
#else
/* fail if given a priority and libipsec was not compiled with
priority support */
if (p_priority != 0)
{
__ipsec_errcode = EIPSEC_PRIORITY_NOT_COMPILED;
return -1;
}
#endif
offset = tlen;
__ipsec_errcode = EIPSEC_NO_ERROR;
return 0;
}
static int
set_x_request(src, dst)
struct sockaddr *src, *dst;
{
struct sadb_x_ipsecrequest *p;
int reqlen;
caddr_t n;
reqlen = sizeof(*p)
+ (src ? sysdep_sa_len(src) : 0)
+ (dst ? sysdep_sa_len(dst) : 0);
tlen += reqlen; /* increment to total length */
n = realloc(pbuf, tlen);
if (n == NULL) {
__ipsec_errcode = EIPSEC_NO_BUFS;
return -1;
}
pbuf = n;
p = (struct sadb_x_ipsecrequest *)&pbuf[offset];
p->sadb_x_ipsecrequest_len = reqlen;
p->sadb_x_ipsecrequest_proto = p_protocol;
p->sadb_x_ipsecrequest_mode = p_mode;
p->sadb_x_ipsecrequest_level = p_level;
p->sadb_x_ipsecrequest_reqid = p_reqid;
offset += sizeof(*p);
if (set_sockaddr(src) || set_sockaddr(dst))
return -1;
__ipsec_errcode = EIPSEC_NO_ERROR;
return 0;
}
static int
set_sockaddr(addr)
struct sockaddr *addr;
{
if (addr == NULL) {
__ipsec_errcode = EIPSEC_NO_ERROR;
return 0;
}
/* tlen has already incremented */
memcpy(&pbuf[offset], addr, sysdep_sa_len(addr));
offset += sysdep_sa_len(addr);
__ipsec_errcode = EIPSEC_NO_ERROR;
return 0;
}
static void
policy_parse_request_init()
{
p_protocol = IPPROTO_IP;
p_mode = IPSEC_MODE_ANY;
p_level = IPSEC_LEVEL_DEFAULT;
p_reqid = 0;
if (p_src != NULL) {
free(p_src);
p_src = NULL;
}
if (p_dst != NULL) {
free(p_dst);
p_dst = NULL;
}
return;
}
static caddr_t
policy_parse(msg, msglen)
char *msg;
int msglen;
{
int error;
pbuf = NULL;
tlen = 0;
/* initialize */
p_dir = IPSEC_DIR_INVALID;
p_type = IPSEC_POLICY_DISCARD;
policy_parse_request_init();
__policy__strbuffer__init__(msg);
error = yyparse(); /* it must be set errcode. */
__policy__strbuffer__free__();
if (error) {
if (pbuf != NULL)
free(pbuf);
return NULL;
}
/* update total length */
((struct sadb_x_policy *)pbuf)->sadb_x_policy_len = PFKEY_UNIT64(tlen);
__ipsec_errcode = EIPSEC_NO_ERROR;
return pbuf;
}
caddr_t
ipsec_set_policy(msg, msglen)
char *msg;
int msglen;
{
caddr_t policy;
policy = policy_parse(msg, msglen);
if (policy == NULL) {
if (__ipsec_errcode == EIPSEC_NO_ERROR)
__ipsec_errcode = EIPSEC_INVAL_ARGUMENT;
return NULL;
}
__ipsec_errcode = EIPSEC_NO_ERROR;
return policy;
}

View File

@ -0,0 +1,185 @@
/* $Id: policy_token.l,v 1.1.1.1 2005/02/12 11:11:36 manu Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
%{
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <net/pfkeyv2.h>
#include <netinet/in.h>
#ifdef HAVE_NETINET6_IPSEC
# include <netinet6/ipsec.h>
#else
# include <netinet/ipsec.h>
#endif
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include "libpfkey.h"
#if !defined(__NetBSD__) && !defined(__FreeBSD__) && !defined(__linux__)
#include "y.tab.h"
#else
#include "policy_parse.h"
#endif
#define yylval __libipseclval /* XXX */
int yylex __P((void));
%}
%option noyywrap
%option nounput
/* common section */
nl \n
ws [ \t]+
digit [0-9]
hexdigit [0-9A-Fa-f]
special [()+\|\?\*,]
dot \.
comma \,
hyphen \-
colon \:
slash \/
bcl \{
ecl \}
blcl \[
elcl \]
percent \%
semi \;
plus \+
usec {dot}{digit}{1,6}
comment \#.*
ccomment "/*"
bracketstring \<[^>]*\>
quotedstring \"[^"]*\"
decstring {digit}+
hexpair {hexdigit}{hexdigit}
hexstring 0[xX]{hexdigit}+
octetstring {octet}({dot}{octet})+
ipaddress [a-zA-Z0-9:\._][a-zA-Z0-9:\._]*(%[a-zA-Z0-9]+)?
%%
in { yylval.num = IPSEC_DIR_INBOUND; return(DIR); }
out { yylval.num = IPSEC_DIR_OUTBOUND; return(DIR); }
fwd {
#ifdef HAVE_POLICY_FWD
yylval.num = IPSEC_DIR_FWD; return(DIR);
#else
yylval.num = IPSEC_DIR_INBOUND; return(DIR);
#endif
}
priority { return(PRIORITY); }
prio { return(PRIORITY); }
low { yylval.num32 = PRIORITY_LOW; return(PRIO_BASE); }
def { yylval.num32 = PRIORITY_DEFAULT; return(PRIO_BASE); }
high { yylval.num32 = PRIORITY_HIGH; return(PRIO_BASE); }
{plus} { return(PLUS); }
{decstring} {
yylval.val.len = strlen(yytext);
yylval.val.buf = yytext;
return(PRIO_OFFSET);
}
discard { yylval.num = IPSEC_POLICY_DISCARD; return(ACTION); }
none { yylval.num = IPSEC_POLICY_NONE; return(ACTION); }
ipsec { yylval.num = IPSEC_POLICY_IPSEC; return(ACTION); }
bypass { yylval.num = IPSEC_POLICY_BYPASS; return(ACTION); }
entrust { yylval.num = IPSEC_POLICY_ENTRUST; return(ACTION); }
esp { yylval.num = IPPROTO_ESP; return(PROTOCOL); }
ah { yylval.num = IPPROTO_AH; return(PROTOCOL); }
ipcomp { yylval.num = IPPROTO_IPCOMP; return(PROTOCOL); }
transport { yylval.num = IPSEC_MODE_TRANSPORT; return(MODE); }
tunnel { yylval.num = IPSEC_MODE_TUNNEL; return(MODE); }
me { return(ME); }
any { return(ANY); }
default { yylval.num = IPSEC_LEVEL_DEFAULT; return(LEVEL); }
use { yylval.num = IPSEC_LEVEL_USE; return(LEVEL); }
require { yylval.num = IPSEC_LEVEL_REQUIRE; return(LEVEL); }
unique{colon}{decstring} {
yylval.val.len = strlen(yytext + 7);
yylval.val.buf = yytext + 7;
return(LEVEL_SPECIFY);
}
unique { yylval.num = IPSEC_LEVEL_UNIQUE; return(LEVEL); }
{slash} { return(SLASH); }
{ipaddress} {
yylval.val.len = strlen(yytext);
yylval.val.buf = yytext;
return(IPADDRESS);
}
{hyphen} { return(HYPHEN); }
{ws} { ; }
{nl} { ; }
%%
void __policy__strbuffer__init__ __P((char *));
void __policy__strbuffer__free__ __P((void));
static YY_BUFFER_STATE strbuffer;
void
__policy__strbuffer__init__(msg)
char *msg;
{
if (YY_CURRENT_BUFFER)
yy_delete_buffer(YY_CURRENT_BUFFER);
strbuffer = (YY_BUFFER_STATE)yy_scan_string(msg);
yy_switch_to_buffer(strbuffer);
return;
}
void
__policy__strbuffer__free__()
{
yy_delete_buffer(strbuffer);
return;
}

View File

@ -0,0 +1,176 @@
/* $KAME: test-policy.c,v 1.16 2003/08/26 03:24:08 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <net/pfkeyv2.h>
#ifdef HAVE_NETINET6_IPSEC
# include <netinet6/ipsec.h>
#else
# include <netinet/ipsec.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <err.h>
#include "libpfkey.h"
struct req_t {
int result; /* expected result; 0:ok 1:ng */
int dump_result; /* dumped result expected to match original: 1:yes 0:no */
char *str;
u_int32_t expected_priority;
} reqs[] = {
#ifdef HAVE_PFKEY_POLICY_PRIORITY
{ 0, 0, "out ipsec esp/transport//require", PRIORITY_DEFAULT },
{ 0, 0, "out prio -1 ipsec esp/transport//require", PRIORITY_DEFAULT + 1 },
{ 0, 0, "out priority 2147483648 ipsec esp/transport//require", 0 },
{ 0, 1, "in prio def ipsec esp/transport//require", PRIORITY_DEFAULT },
{ 0, 1, "in prio low ipsec esp/transport//require", PRIORITY_LOW },
{ 0, 1, "in prio high ipsec esp/transport//require", PRIORITY_HIGH },
{ 0, 1, "in prio def + 1 ipsec esp/transport//require", PRIORITY_DEFAULT - 1 },
{ 0, 1, "in prio def - 1 ipsec esp/transport//require", PRIORITY_DEFAULT + 1},
{ 0, 1, "in prio low + 1 ipsec esp/transport//require", PRIORITY_LOW - 1 },
{ 0, 1, "in prio low - 1 ipsec esp/transport//require", PRIORITY_LOW + 1 },
{ 0, 1, "in prio high + 1 ipsec esp/transport//require", PRIORITY_HIGH - 1 },
{ 0, 1, "in prio high - 1 ipsec esp/transport//require", PRIORITY_HIGH + 1 },
{ 1, 0, "in prio low - -1 ipsec esp/transport//require", 0 },
{ 1, 0, "in prio low + high ipsec esp/transport//require", 0 },
#else
{ 0, 1, "out ipsec esp/transport//require", 0 },
{ 1, 0, "out prio -1 ipsec esp/transport//require", 0 },
{ 1, 0, "in prio def ipsec esp/transport//require", 0 },
{ 1, 0, "in prio def + 1 ipsec esp/transport//require", 0 },
#endif
};
int test1 __P((void));
int test1sub1 __P((struct req_t *));
int test1sub2 __P((char *, int));
int test2 __P((void));
int test2sub __P((int));
int
main(ac, av)
int ac;
char **av;
{
return test1();
}
int
test1()
{
int i;
int result;
int error = 0;
printf("TEST1\n");
for (i = 0; i < sizeof(reqs)/sizeof(reqs[0]); i++) {
printf("#%d [%s]\n", i + 1, reqs[i].str);
result = test1sub1(&reqs[i]);
if (result == 0 && reqs[i].result == 1) {
error = 1;
warnx("ERROR: expecting failure.");
} else if (result == 1 && reqs[i].result == 0) {
error = 1;
warnx("ERROR: expecting success.");
}
}
return error;
}
int
test1sub1(req)
struct req_t *req;
{
char *policy;
char *policy_str;
struct sadb_x_policy *xpl;
int len;
policy = ipsec_set_policy(req->str, strlen(req->str));
if (policy == NULL) {
if (req->result == 0) {
printf("ipsec_set_policy: %s\n", ipsec_strerror());
}
return 1;
}
#ifdef HAVE_PFKEY_POLICY_PRIORITY
/* check priority matches expected */
xpl = (struct sadb_x_policy *)policy;
if (xpl->sadb_x_policy_priority != req->expected_priority) {
printf("Actual priority %u does not match expected priority %u\n",
xpl->sadb_x_policy_priority, req->expected_priority);
free(policy);
return 1;
}
#endif
if (req->dump_result) {
/* invert policy */
len = ipsec_get_policylen(policy);
if ((policy_str = ipsec_dump_policy(policy, NULL)) == NULL) {
printf("%s\n", ipsec_strerror());
free(policy);
return 1;
}
/* check that they match */
if (strcmp(req->str, policy_str) != 0) {
printf("ipsec_dump_policy result (%s) does not match original "
"(%s)\n", policy_str, req->str);
free(policy_str);
free(policy);
return 1;
}
free(policy_str);
}
free(policy);
return 0;
}

View File

@ -0,0 +1,330 @@
/* $KAME: test-policy.c,v 1.16 2003/08/26 03:24:08 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <net/pfkeyv2.h>
#include <netinet/ipsec.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <err.h>
#include "libpfkey.h"
struct req_t {
int result; /* expected result; 0:ok 1:ng */
char *str;
} reqs[] = {
{ 0, "out ipsec" },
{ 1, "must_error" },
{ 1, "in ipsec must_error" },
{ 1, "out ipsec esp/must_error" },
{ 1, "out discard" },
{ 1, "out none" },
{ 0, "in entrust" },
{ 0, "out entrust" },
{ 1, "out ipsec esp" },
{ 0, "in ipsec ah/transport" },
{ 1, "in ipsec ah/tunnel" },
{ 0, "out ipsec ah/transport/" },
{ 1, "out ipsec ah/tunnel/" },
{ 0, "in ipsec esp / transport / 10.0.0.1-10.0.0.2" },
{ 0, "in ipsec esp/tunnel/::1-::2" },
{ 1, "in ipsec esp/tunnel/10.0.0.1-::2" },
{ 0, "in ipsec esp/tunnel/::1-::2/require" },
{ 0, "out ipsec ah/transport//use" },
{ 1, "out ipsec ah/transport esp/use" },
{ 1, "in ipsec ah/transport esp/tunnel" },
{ 0, "in ipsec ah/transport esp/tunnel/::1-::1" },
{ 0, "in ipsec
ah / transport
esp / tunnel / ::1-::2" },
{ 0, "out ipsec
ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require
ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require
ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require
" },
{ 0, "out ipsec esp/transport/fec0::10-fec0::11/use" },
};
int test1 __P((void));
int test1sub1 __P((struct req_t *));
int test1sub2 __P((char *, int));
int test2 __P((void));
int test2sub __P((int));
int
main(ac, av)
int ac;
char **av;
{
test1();
test2();
exit(0);
}
int
test1()
{
int i;
int result;
printf("TEST1\n");
for (i = 0; i < sizeof(reqs)/sizeof(reqs[0]); i++) {
printf("#%d [%s]\n", i + 1, reqs[i].str);
result = test1sub1(&reqs[i]);
if (result == 0 && reqs[i].result == 1) {
warnx("ERROR: expecting failure.");
} else if (result == 1 && reqs[i].result == 0) {
warnx("ERROR: expecting success.");
}
}
return 0;
}
int
test1sub1(req)
struct req_t *req;
{
char *buf;
buf = ipsec_set_policy(req->str, strlen(req->str));
if (buf == NULL) {
printf("ipsec_set_policy: %s\n", ipsec_strerror());
return 1;
}
if (test1sub2(buf, PF_INET) != 0
|| test1sub2(buf, PF_INET6) != 0) {
free(buf);
return 1;
}
#if 0
kdebug_sadb_x_policy((struct sadb_ext *)buf);
#endif
free(buf);
return 0;
}
int
test1sub2(policy, family)
char *policy;
int family;
{
int so;
int proto = 0, optname = 0;
int len;
char getbuf[1024];
switch (family) {
case PF_INET:
proto = IPPROTO_IP;
optname = IP_IPSEC_POLICY;
break;
case PF_INET6:
proto = IPPROTO_IPV6;
optname = IPV6_IPSEC_POLICY;
break;
}
if ((so = socket(family, SOCK_DGRAM, 0)) < 0)
err(1, "socket");
len = ipsec_get_policylen(policy);
#if 0
printf("\tsetlen:%d\n", len);
#endif
if (setsockopt(so, proto, optname, policy, len) < 0) {
printf("fail to set sockopt; %s\n", strerror(errno));
close(so);
return 1;
}
memset(getbuf, 0, sizeof(getbuf));
memcpy(getbuf, policy, sizeof(struct sadb_x_policy));
if (getsockopt(so, proto, optname, getbuf, &len) < 0) {
printf("fail to get sockopt; %s\n", strerror(errno));
close(so);
return 1;
}
{
char *buf = NULL;
#if 0
printf("\tgetlen:%d\n", len);
#endif
if ((buf = ipsec_dump_policy(getbuf, NULL)) == NULL) {
printf("%s\n", ipsec_strerror());
close(so);
return 1;
}
#if 0
printf("\t[%s]\n", buf);
#endif
free(buf);
}
close (so);
return 0;
}
char addr[] = {
28, 28, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
0, 0, 0, 0,
};
int
test2()
{
int so;
char *pol1 = "out ipsec";
char *pol2 = "out ipsec ah/transport//use";
char *sp1, *sp2;
int splen1, splen2;
int spid;
struct sadb_msg *m;
printf("TEST2\n");
if (getuid() != 0)
errx(1, "root privilege required.");
sp1 = ipsec_set_policy(pol1, strlen(pol1));
splen1 = ipsec_get_policylen(sp1);
sp2 = ipsec_set_policy(pol2, strlen(pol2));
splen2 = ipsec_get_policylen(sp2);
if ((so = pfkey_open()) < 0)
errx(1, "ERROR: %s", ipsec_strerror());
printf("spdflush()\n");
if (pfkey_send_spdflush(so) < 0)
errx(1, "ERROR: %s", ipsec_strerror());
m = pfkey_recv(so);
free(m);
printf("spdsetidx()\n");
if (pfkey_send_spdsetidx(so, (struct sockaddr *)addr, 128,
(struct sockaddr *)addr, 128,
255, sp1, splen1, 0) < 0)
errx(1, "ERROR: %s", ipsec_strerror());
m = pfkey_recv(so);
free(m);
printf("spdupdate()\n");
if (pfkey_send_spdupdate(so, (struct sockaddr *)addr, 128,
(struct sockaddr *)addr, 128,
255, sp2, splen2, 0) < 0)
errx(1, "ERROR: %s", ipsec_strerror());
m = pfkey_recv(so);
free(m);
printf("sleep(4)\n");
sleep(4);
printf("spddelete()\n");
if (pfkey_send_spddelete(so, (struct sockaddr *)addr, 128,
(struct sockaddr *)addr, 128,
255, sp1, splen1, 0) < 0)
errx(1, "ERROR: %s", ipsec_strerror());
m = pfkey_recv(so);
free(m);
printf("spdadd()\n");
if (pfkey_send_spdadd(so, (struct sockaddr *)addr, 128,
(struct sockaddr *)addr, 128,
255, sp2, splen2, 0) < 0)
errx(1, "ERROR: %s", ipsec_strerror());
spid = test2sub(so);
printf("spdget(%u)\n", spid);
if (pfkey_send_spdget(so, spid) < 0)
errx(1, "ERROR: %s", ipsec_strerror());
m = pfkey_recv(so);
free(m);
printf("sleep(4)\n");
sleep(4);
printf("spddelete2()\n");
if (pfkey_send_spddelete2(so, spid) < 0)
errx(1, "ERROR: %s", ipsec_strerror());
m = pfkey_recv(so);
free(m);
printf("spdadd() with lifetime's 10(s)\n");
if (pfkey_send_spdadd2(so, (struct sockaddr *)addr, 128,
(struct sockaddr *)addr, 128,
255, 0, 10, sp2, splen2, 0) < 0)
errx(1, "ERROR: %s", ipsec_strerror());
spid = test2sub(so);
/* expecting failure */
printf("spdupdate()\n");
if (pfkey_send_spdupdate(so, (struct sockaddr *)addr, 128,
(struct sockaddr *)addr, 128,
255, sp2, splen2, 0) == 0) {
warnx("ERROR: expecting failure.");
}
return 0;
}
int
test2sub(so)
int so;
{
struct sadb_msg *msg;
caddr_t mhp[SADB_EXT_MAX + 1];
if ((msg = pfkey_recv(so)) == NULL)
errx(1, "ERROR: pfkey_recv failure.");
if (pfkey_align(msg, mhp) < 0)
errx(1, "ERROR: pfkey_align failure.");
return ((struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY])->sadb_x_policy_id;
}

View File

@ -0,0 +1,22 @@
cfparse.c
cfparse.h
cftoken.c
y.tab.h
Makefile
Makefile.in
config.status
config.log
.depend
.deps
.libs
eaytest
racoon
racoonctl
autom4te.cache
configure
config.h
config.h.in
plainrsa-gen
prsa_par.c
prsa_par.h
prsa_tok.c

View File

@ -0,0 +1,156 @@
# $Id: Makefile.am,v 1.1.1.1 2005/02/12 11:11:37 manu Exp $
sbin_PROGRAMS = racoon racoonctl plainrsa-gen
noinst_PROGRAMS = eaytest
include_racoon_HEADERS = racoonctl.h var.h vmbuf.h misc.h gcmalloc.h admin.h \
schedule.h sockmisc.h vmbuf.h isakmp_var.h isakmp.h isakmp_xauth.h \
isakmp_cfg.h isakmp_unity.h ipsec_doi.h evt.h
lib_LTLIBRARIES = libracoon.la
adminsockdir=${localstatedir}/racoon
INCLUDES = -I${srcdir}/../libipsec
AM_CFLAGS = @GLIBC_BUGS@ -DSYSCONFDIR=\"${sysconfdir}\" \
-DADMINPORTDIR=\"${adminsockdir}\"
AM_LDFLAGS = -lcrypto
MISSING_ALGOS = \
missing/crypto/sha2/sha2.c \
missing/crypto/rijndael/rijndael-api-fst.c \
missing/crypto/rijndael/rijndael-alg-fst.c
racoon_SOURCES = \
main.c session.c isakmp.c handler.c \
isakmp_ident.c isakmp_agg.c isakmp_base.c \
isakmp_quick.c isakmp_inf.c isakmp_newg.c \
gssapi.c dnssec.c getcertsbyname.c privsep.c \
pfkey.c admin.c evt.c ipsec_doi.c oakley.c grabmyaddr.c vendorid.c \
policy.c localconf.c remoteconf.c crypto_openssl.c algorithm.c \
proposal.c sainfo.c strnames.c \
plog.c logger.c schedule.c str2val.c \
safefile.c backupsa.c genlist.c rsalist.c \
cftoken.l cfparse.y prsa_tok.l prsa_par.y
EXTRA_racoon_SOURCES = isakmp_xauth.c isakmp_cfg.c isakmp_unity.c throttle.c \
isakmp_frag.c nattraversal.c $(MISSING_ALGOS)
racoon_LDFLAGS = ../libipsec/libipsec.la
racoon_LDADD = $(CRYPTOBJS) $(HYBRID_OBJS) $(NATT_OBJS) $(FRAG_OBJS) $(LEXLIB) \
vmbuf.o sockmisc.o misc.o
racoon_DEPENDENCIES = ../libipsec/libipsec.la \
$(CRYPTOBJS) $(HYBRID_OBJS) $(NATT_OBJS) $(FRAG_OBJS) \
vmbuf.o sockmisc.o misc.o
racoonctl_SOURCES = racoonctl.c str2val.c
racoonctl_LDFLAGS = libracoon.la ../libipsec/libipsec.la
racoonctl_DEPENDENCIES = ../libipsec/libipsec.la libracoon.la
libracoon_la_SOURCES = kmpstat.c vmbuf.c sockmisc.c misc.c
plainrsa_gen_SOURCES = plainrsa-gen.c plog.c \
crypto_openssl.c logger.c
EXTRA_plainrsa_gen_SOURCES = $(MISSING_ALGOS)
plainrsa_gen_LDADD = $(CRYPTOBJS) vmbuf.o misc.o
plainrsa_gen_DEPENDENCIES = $(CRYPTOBJS) vmbuf.o misc.o
eaytest_SOURCES = eaytest.c plog.c logger.c
EXTRA_eaytest_SOURCES = missing/crypto/sha2/sha2.c
eaytest_LDADD = crypto_openssl_test.o vmbuf.o str2val.o misc_noplog.o \
$(CRYPTOBJS)
eaytest_DEPENDENCIES = crypto_openssl_test.o vmbuf.o str2val.o \
misc_noplog.o $(CRYPTOBJS)
noinst_HEADERS = \
admin.h dnssec.h isakmp_base.h oakley.h session.h \
admin_var.h dump.h isakmp_ident.h pfkey.h sockmisc.h \
algorithm.h gcmalloc.h isakmp_inf.h plog.h str2val.h \
backupsa.h gnuc.h isakmp_newg.h policy.h strnames.h \
grabmyaddr.h isakmp_quick.h proposal.h var.h evt.h \
gssapi.h isakmp_var.h vendorid.h nattraversal.h\
crypto_openssl.h handler.h localconf.h remoteconf.h vmbuf.h \
debug.h ipsec_doi.h logger.h safefile.h \
debugrm.h isakmp.h misc.h sainfo.h \
dhgroup.h isakmp_agg.h netdb_dnssec.h schedule.h \
isakmp_cfg.h isakmp_xauth.h isakmp_unity.h isakmp_frag.h \
throttle.h privsep.h \
cfparse_proto.h cftoken_proto.h genlist.h rsalist.h \
missing/crypto/sha2/sha2.h missing/crypto/rijndael/rijndael_local.h \
missing/crypto/rijndael/rijndael-api-fst.h \
missing/crypto/rijndael/rijndael-alg-fst.h \
missing/crypto/rijndael/rijndael.h
man5_MANS = racoon.conf.5
man8_MANS = racoon.8 racoonctl.8 plainrsa-gen.8
EXTRA_DIST = \
${man5_MANS} ${man8_MANS} \
missing/crypto/rijndael/boxes-fst.dat \
doc/FAQ doc/README.certificate doc/README.gssapi \
contrib/sp.pl stats.pl \
samples/psk.txt.sample samples/racoon.conf.sample \
samples/psk.txt.in samples/racoon.conf.in \
samples/racoon.conf.sample-gssapi samples/racoon.conf.sample-natt \
samples/racoon.conf.sample-inherit samples/racoon.conf.sample-plainrsa \
samples/roadwarrior/README \
samples/roadwarrior/client/phase1-down.sh \
samples/roadwarrior/client/phase1-up.sh \
samples/roadwarrior/client/racoon.conf \
samples/roadwarrior/server/phase1-down.sh \
samples/roadwarrior/server/racoon.conf \
samples/roadwarrior/server/racoon.conf-radius
DISTCLEANFILES = cfparse.c cftoken.c prsa_tok.c prsa_par.c cfparse.h prsa_par.h
TESTS = eaytest
install-exec-local:
${mkinstalldirs} $(DESTDIR)${adminsockdir}
# Config file parser
cftoken.o: cftoken.c cfparse.h
$(COMPILE) -c -o $@ $<
cfparse.o: cfparse.c
$(COMPILE) -c -o $@ $<
cftoken.c: cftoken.l
$(LEX) -ocftoken.c $(srcdir)/cftoken.l
cfparse.h cfparse.c: $(srcdir)/cfparse.y
$(YACC) -d $(srcdir)/cfparse.y
mv y.tab.c cfparse.c
mv y.tab.h cfparse.h
# Plain-RSA parser
prsa_tok.o: prsa_tok.c prsa_par.h
$(COMPILE) -c -o $@ $<
prsa_par.o: prsa_par.c
$(COMPILE) -c -o $@ $<
prsa_tok.c: $(srcdir)/prsa_tok.l
$(LEX) -Pprsa -oprsa_tok.c $(srcdir)/prsa_tok.l
prsa_par.h prsa_par.c: $(srcdir)/prsa_par.y
$(YACC) -pprsa -d $(srcdir)/prsa_par.y
mv y.tab.c prsa_par.c
mv y.tab.h prsa_par.h
# special object rules
crypto_openssl_test.o: crypto_openssl.c
$(COMPILE) -DEAYDEBUG -o crypto_openssl_test.o -c $(srcdir)/crypto_openssl.c
misc_noplog.o: misc.c
$(COMPILE) -DNOUSE_PLOG -o misc_noplog.o -c $(srcdir)/misc.c
# missing/*.c
strdup.o: $(srcdir)/missing/strdup.c
$(COMPILE) -c $(srcdir)/missing/$*.c
getaddrinfo.o: $(srcdir)/missing/getaddrinfo.c
$(COMPILE) -c $(srcdir)/missing/$*.c
getnameinfo.o: $(srcdir)/missing/getnameinfo.c
$(COMPILE) -c $(srcdir)/missing/$*.c
rijndael-api-fst.o: $(srcdir)/missing/crypto/rijndael/rijndael-api-fst.c
$(COMPILE) -c $(srcdir)/missing/crypto/rijndael/$*.c
rijndael-alg-fst.o: $(srcdir)/missing/crypto/rijndael/rijndael-alg-fst.c
$(COMPILE) -c $(srcdir)/missing/crypto/rijndael/$*.c
sha2.o: $(srcdir)/missing/crypto/sha2/sha2.c
$(COMPILE) -c $(srcdir)/missing/crypto/sha2/$*.c

131
crypto/dist/ipsec-tools/src/racoon/TODO vendored Normal file
View File

@ -0,0 +1,131 @@
$KAME: TODO,v 1.36 2001/09/19 09:41:39 sakane Exp $
Please send any questions or bug reports to snap-users@kame.net.
TODO list
URGENT
o The documents for users convenience.
o split log file based on client. printf-like config directive, i.e.
"logfile racoon.%s.log", should be useful here.
-> beware of possible security issue, don't use sprintf() directly!
make validation before giving a string to sprintf().
o save decrypted IKE packet in tcpdump format
o IPComp SA with wellknown CPI in CPI field. how to handle it?
o better rekey
MUST
o multiple certificate payload handling.
o To consider the use with certificate infrastructure. PXIX ???
o kmstat should be improved.
o Informational Exchange processing properly.
o require less configuration. phase 2 is easier (as kernel presents racoon
some hints), phase 1 is harder. for example,
- grab phase 2 lifetime and algorith configuration from sadb_comb payloads in
ACQUIRE message.
- give reasonable default behavior when no configuration file is present.
- difficult items:
how to guess a reasonable phase 1 SA lifetime
(hardcoded default? guess from phase 2 lifetime?)
guess what kind of ID payload to use
guess what kind of authentication to be used
guess phase 1 DH group (for aggressive mode, we cannot negotiate it)
guess if we need phase 2 PFS or not (we cannot negotiate it. so
we may need to pick from "no PFS" or "same as phase 1 DH group")
guess how we should negotiate lifetime
(is "strict" a reasonable default?)
guess which mode to use for phase 1 negotiation (is main mode useful?
is base mode popular enough?)
o more acceptable check.
SHOULD
o psk.txt should be a database? (psk.db?) psk_mkdb?
o Dynamically retry to exchange and resend the packet per nodes.
o To make the list of supported algorithm by sadb_supported payload
in the SADB_REGISTER message which happens asynchronously.
o fix the structure of ph2handle.
We can handle the below case.
node A node B
+--------------SA1----------------+
+--------------SA2----------------+
at node A:
kernel
acquire(A-B) ------> ph2handle(A=B) -----> ph1handle
|
policy
A=B
A=B
But we can not handle the below case because there is no x?handle.
node A node B node C
+--------------SA1----------------+
+------------------------------------------------SA2---------------+
at node A:
kernel
acquire(A-C) ---+---> x?handle ---+---> ph2handle(A=B) -------> ph1handle
| | |
acquire(A-B) ---+ policy +---> ph2handle(A=C) -------> ph1handle
A=B
A=C
o consistency of function name.
o deep copy configuration entry to hander. It's easy to reload configuration.
o don't keep to hold keymat values, do it ?
o local address's field in isakmpsa handler must be kicked out to rmconf.
o responder policy and initiator policy should be separated.
o for lifetime and key length, something like this should be useful.
- propose N
- accept between X and Y
o wildcard "accept any proposal" policy should be allowed.
o replay prevention
- limited total number of session
- limited session per peer
- number of proposal
o full support for variable length SPI. quickhack support for IPComp is done.
MAY
o Effective code.
o interaction between IKE/IPsec and socket layer.
at this moment, IKE/IPsec failure is modeled as total packet loss to other
part of network subsystem, including socket layer. this presents the
following behaviors:
- annoyingly long timeouts on tcp connection attempt, and IKE failure;
need to wait till tcp socket timeouts.
- blackhole if there's mismatching SAs.
we may be able to give socket layer some feedback from IKE/IPsec layer.
still not sure if those make sense or not.
for example:
- send PRU_HOSTDEAD to sockets if IKE negotiation failed
(sys/netkey/key.c:key_acquire2)
to do this, we need to remember which ACQUIRE was caused by which socket,
possibly into larval SAs.
- PRU_QUENCH on "no SA found on output"
- kick tcp retransmission timer on first SA establishment
o IKE daemon should handle situations where peer does not run IKE daemon
(UDP port unreach for port 500) better.
should use connected UDP sockets for sending IKE datagrams.
o rate-limit log messages from kernel IPsec errors, like "no SA found".
TO BE TESTED.
o IKE retransmit behavior
see, draft-*-ipsec-rekeying*.txt
o Reboot recovery (peer reboot losing it's security associations)
see, draft-*-ipsec-rekeying*.txt
o Scenarios
- End-to-End transport long lived security associations
(over night, data transfer >1Gb) with frequent dynamic rekey
- End-to-GW tunnel long lived security associations
(over night, data transfer >1Gb) with frequent dynamic rekey
- Policy change events while under SA load
- End-to-End SA through IPsec tunnels, initiation both ways
- Client End-to-End through client-to-GW tunnel SA, initiate from
client for tunnel, then initiation both ways for end-to-end
- Client-to-GW transport SA for secure management
o behavior to receive multiple auth method proposals and AND proposal
and to be written many many.

View File

@ -0,0 +1,649 @@
/* $Id: admin.c,v 1.1.1.1 2005/02/12 11:11:38 manu Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#include "config.h"
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/signal.h>
#include <sys/stat.h>
#include <sys/un.h>
#include <net/pfkeyv2.h>
#include <netinet/in.h>
#ifndef HAVE_NETINET6_IPSEC
#include <netinet/ipsec.h>
#else
#include <netinet6/ipsec.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <netdb.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include "var.h"
#include "misc.h"
#include "vmbuf.h"
#include "plog.h"
#include "sockmisc.h"
#include "debug.h"
#include "schedule.h"
#include "localconf.h"
#include "remoteconf.h"
#include "grabmyaddr.h"
#include "isakmp_var.h"
#include "isakmp.h"
#include "oakley.h"
#include "handler.h"
#include "evt.h"
#include "pfkey.h"
#include "ipsec_doi.h"
#include "admin.h"
#include "admin_var.h"
#include "isakmp_inf.h"
#include "session.h"
#include "gcmalloc.h"
#ifdef ENABLE_ADMINPORT
char *adminsock_path = ADMINSOCK_PATH;
uid_t adminsock_owner = 0;
gid_t adminsock_group = 0;
mode_t adminsock_mode = 0600;
static struct sockaddr_un sunaddr;
static int admin_process __P((int, char *));
static int admin_reply __P((int, struct admin_com *, vchar_t *));
static void isakmp_flush_sa __P((struct ph1handle *, char *, char *));
int
admin_handler()
{
int so2;
struct sockaddr_storage from;
int fromlen = sizeof(from);
struct admin_com com;
char *combuf = NULL;
pid_t pid = -1;
int len, error = -1;
so2 = accept(lcconf->sock_admin, (struct sockaddr *)&from, &fromlen);
if (so2 < 0) {
plog(LLV_ERROR, LOCATION, NULL,
"failed to accept admin command: %s\n",
strerror(errno));
return -1;
}
/* get buffer length */
while ((len = recv(so2, (char *)&com, sizeof(com), MSG_PEEK)) < 0) {
if (errno == EINTR)
continue;
plog(LLV_ERROR, LOCATION, NULL,
"failed to recv admin command: %s\n",
strerror(errno));
goto end;
}
/* sanity check */
if (len < sizeof(com)) {
plog(LLV_ERROR, LOCATION, NULL,
"invalid header length of admin command\n");
goto end;
}
/* get buffer to receive */
if ((combuf = racoon_malloc(com.ac_len)) == 0) {
plog(LLV_ERROR, LOCATION, NULL,
"failed to alloc buffer for admin command\n");
goto end;
}
/* get real data */
while ((len = recv(so2, combuf, com.ac_len, 0)) < 0) {
if (errno == EINTR)
continue;
plog(LLV_ERROR, LOCATION, NULL,
"failed to recv admin command: %s\n",
strerror(errno));
goto end;
}
if (com.ac_cmd == ADMIN_RELOAD_CONF) {
/* reload does not work at all! */
signal_handler(SIGHUP);
goto end;
}
error = admin_process(so2, combuf);
end:
(void)close(so2);
if (combuf)
racoon_free(combuf);
/* exit if child's process. */
if (pid == 0 && !f_foreground)
exit(error);
return error;
}
/*
* main child's process.
*/
static int
admin_process(so2, combuf)
int so2;
char *combuf;
{
struct admin_com *com = (struct admin_com *)combuf;
vchar_t *buf = NULL;
vchar_t *id = NULL;
vchar_t *key = NULL;
int idtype = 0;
int error = 0;
com->ac_errno = 0;
switch (com->ac_cmd) {
case ADMIN_RELOAD_CONF:
/* don't entered because of proccessing it in other place. */
plog(LLV_ERROR, LOCATION, NULL, "should never reach here\n");
goto bad;
case ADMIN_SHOW_SCHED:
{
caddr_t p;
int len;
if (sched_dump(&p, &len) == -1)
com->ac_errno = -1;
buf = vmalloc(len);
if (buf == NULL)
com->ac_errno = -1;
else
memcpy(buf->v, p, len);
}
break;
case ADMIN_SHOW_EVT:
/* It's not really an error, don't force racoonctl to quit */
if ((buf = evt_dump()) == NULL)
com->ac_errno = 0;
break;
case ADMIN_SHOW_SA:
case ADMIN_FLUSH_SA:
{
switch (com->ac_proto) {
case ADMIN_PROTO_ISAKMP:
switch (com->ac_cmd) {
case ADMIN_SHOW_SA:
buf = dumpph1();
if (buf == NULL)
com->ac_errno = -1;
break;
case ADMIN_FLUSH_SA:
flushph1();
break;
}
break;
case ADMIN_PROTO_IPSEC:
case ADMIN_PROTO_AH:
case ADMIN_PROTO_ESP:
switch (com->ac_cmd) {
case ADMIN_SHOW_SA:
{
u_int p;
p = admin2pfkey_proto(com->ac_proto);
if (p == -1)
goto bad;
buf = pfkey_dump_sadb(p);
if (buf == NULL)
com->ac_errno = -1;
}
break;
case ADMIN_FLUSH_SA:
pfkey_flush_sadb(com->ac_proto);
break;
}
break;
case ADMIN_PROTO_INTERNAL:
switch (com->ac_cmd) {
case ADMIN_SHOW_SA:
buf = NULL; /*XXX dumpph2(&error);*/
if (buf == NULL)
com->ac_errno = error;
break;
case ADMIN_FLUSH_SA:
/*XXX flushph2();*/
com->ac_errno = 0;
break;
}
break;
default:
/* ignore */
com->ac_errno = -1;
}
}
break;
case ADMIN_DELETE_SA: {
struct ph1handle *iph1;
struct sockaddr *dst;
struct sockaddr *src;
char *loc, *rem;
src = (struct sockaddr *)
&((struct admin_com_indexes *)
((caddr_t)com + sizeof(*com)))->src;
dst = (struct sockaddr *)
&((struct admin_com_indexes *)
((caddr_t)com + sizeof(*com)))->dst;
if ((loc = strdup(saddrwop2str(src))) == NULL) {
plog(LLV_ERROR, LOCATION, NULL,
"cannot allocate memory\n");
break;
}
if ((rem = strdup(saddrwop2str(dst))) == NULL) {
plog(LLV_ERROR, LOCATION, NULL,
"cannot allocate memory\n");
break;
}
if ((iph1 = getph1byaddr(src, dst)) == NULL) {
plog(LLV_ERROR, LOCATION, NULL,
"phase 1 for %s -> %s not found\n", loc, rem);
} else {
isakmp_flush_sa(iph1, loc, rem);
}
racoon_free(loc);
racoon_free(rem);
break;
}
case ADMIN_DELETE_ALL_SA_DST: {
struct ph1handle *iph1;
struct sockaddr *dst;
char *loc, *rem;
dst = (struct sockaddr *)
&((struct admin_com_indexes *)
((caddr_t)com + sizeof(*com)))->dst;
if ((rem = strdup(saddrwop2str(dst))) == NULL) {
plog(LLV_ERROR, LOCATION, NULL,
"cannot allocate memory\n");
break;
}
plog(LLV_INFO, LOCATION, NULL,
"Flushing all SA for peer %s\n", rem);
while ((iph1 = getph1bydstaddr(dst)) != NULL) {
if ((loc = strdup(saddrwop2str(iph1->local))) == NULL) {
plog(LLV_ERROR, LOCATION, NULL,
"cannot allocate memory\n");
break;
}
isakmp_flush_sa(iph1, loc, rem);
racoon_free(loc);
}
racoon_free(rem);
break;
}
case ADMIN_ESTABLISH_SA_PSK: {
struct admin_com_psk *acp;
char *data;
com->ac_cmd = ADMIN_ESTABLISH_SA;
acp = (struct admin_com_psk *)
((char *)com + sizeof(*com) +
sizeof(struct admin_com_indexes));
idtype = acp->id_type;
if ((id = vmalloc(acp->id_len)) == NULL) {
plog(LLV_ERROR, LOCATION, NULL,
"cannot allocate memory: %s\n",
strerror(errno));
break;
}
data = (char *)(acp + 1);
memcpy(id->v, data, id->l);
if ((key = vmalloc(acp->key_len)) == NULL) {
plog(LLV_ERROR, LOCATION, NULL,
"cannot allocate memory: %s\n",
strerror(errno));
vfree(id);
break;
}
data = (char *)(data + acp->id_len);
memcpy(key->v, data, key->l);
}
/* FALLTHROUGH */
case ADMIN_ESTABLISH_SA:
{
struct sockaddr *dst;
struct sockaddr *src;
src = (struct sockaddr *)
&((struct admin_com_indexes *)
((caddr_t)com + sizeof(*com)))->src;
dst = (struct sockaddr *)
&((struct admin_com_indexes *)
((caddr_t)com + sizeof(*com)))->dst;
switch (com->ac_proto) {
case ADMIN_PROTO_ISAKMP:
{
struct remoteconf *rmconf;
struct sockaddr *remote;
struct sockaddr *local;
/* search appropreate configuration */
rmconf = getrmconf(dst);
if (rmconf == NULL) {
plog(LLV_ERROR, LOCATION, NULL,
"no configuration found "
"for %s\n", saddrwop2str(dst));
com->ac_errno = -1;
break;
}
/* get remote IP address and port number. */
remote = dupsaddr(dst);
if (remote == NULL) {
com->ac_errno = -1;
break;
}
switch (remote->sa_family) {
case AF_INET:
((struct sockaddr_in *)remote)->sin_port =
((struct sockaddr_in *)rmconf->remote)->sin_port;
break;
#ifdef INET6
case AF_INET6:
((struct sockaddr_in6 *)remote)->sin6_port =
((struct sockaddr_in6 *)rmconf->remote)->sin6_port;
break;
#endif
default:
plog(LLV_ERROR, LOCATION, NULL,
"invalid family: %d\n",
remote->sa_family);
com->ac_errno = -1;
break;
}
/* get local address */
local = dupsaddr(src);
if (local == NULL) {
com->ac_errno = -1;
break;
}
switch (local->sa_family) {
case AF_INET:
((struct sockaddr_in *)local)->sin_port =
getmyaddrsport(local);
break;
#ifdef INET6
case AF_INET6:
((struct sockaddr_in6 *)local)->sin6_port =
getmyaddrsport(local);
break;
#endif
default:
plog(LLV_ERROR, LOCATION, NULL,
"invalid family: %d\n",
local->sa_family);
com->ac_errno = -1;
break;
}
/* Set the id and key */
if (id && key) {
if (rmconf->idv != NULL) {
vfree(rmconf->idv);
rmconf->idv = NULL;
}
if (rmconf->key != NULL) {
vfree(rmconf->key);
rmconf->key = NULL;
}
rmconf->idvtype = idtype;
rmconf->idv = id;
rmconf->key = key;
}
plog(LLV_INFO, LOCATION, NULL,
"accept a request to establish IKE-SA: "
"%s\n", saddrwop2str(remote));
/* begin ident mode */
if (isakmp_ph1begin_i(rmconf, remote, local) < 0) {
com->ac_errno = -1;
break;
}
}
break;
case ADMIN_PROTO_AH:
case ADMIN_PROTO_ESP:
break;
default:
/* ignore */
com->ac_errno = -1;
}
}
break;
default:
plog(LLV_ERROR, LOCATION, NULL,
"invalid command: %d\n", com->ac_cmd);
com->ac_errno = -1;
}
if (admin_reply(so2, com, buf) < 0)
goto bad;
if (buf != NULL)
vfree(buf);
return 0;
bad:
if (buf != NULL)
vfree(buf);
return -1;
}
static int
admin_reply(so, combuf, buf)
int so;
struct admin_com *combuf;
vchar_t *buf;
{
int tlen;
char *retbuf = NULL;
if (buf != NULL)
tlen = sizeof(*combuf) + buf->l;
else
tlen = sizeof(*combuf);
retbuf = racoon_calloc(1, tlen);
if (retbuf == NULL) {
plog(LLV_ERROR, LOCATION, NULL,
"failed to allocate admin buffer\n");
return -1;
}
memcpy(retbuf, combuf, sizeof(*combuf));
((struct admin_com *)retbuf)->ac_len = tlen;
if (buf != NULL)
memcpy(retbuf + sizeof(*combuf), buf->v, buf->l);
tlen = send(so, retbuf, tlen, 0);
racoon_free(retbuf);
if (tlen < 0) {
plog(LLV_ERROR, LOCATION, NULL,
"failed to send admin command: %s\n",
strerror(errno));
return -1;
}
return 0;
}
/* ADMIN_PROTO -> SADB_SATYPE */
int
admin2pfkey_proto(proto)
u_int proto;
{
switch (proto) {
case ADMIN_PROTO_IPSEC:
return SADB_SATYPE_UNSPEC;
case ADMIN_PROTO_AH:
return SADB_SATYPE_AH;
case ADMIN_PROTO_ESP:
return SADB_SATYPE_ESP;
default:
plog(LLV_ERROR, LOCATION, NULL,
"unsupported proto for admin: %d\n", proto);
return -1;
}
/*NOTREACHED*/
}
int
admin_init()
{
if (adminsock_path == NULL)
return 0;
memset(&sunaddr, 0, sizeof(sunaddr));
sunaddr.sun_family = AF_UNIX;
snprintf(sunaddr.sun_path, sizeof(sunaddr.sun_path),
"%s", adminsock_path);
lcconf->sock_admin = socket(AF_UNIX, SOCK_STREAM, 0);
if (lcconf->sock_admin == -1) {
plog(LLV_ERROR, LOCATION, NULL,
"socket: %s\n", strerror(errno));
return -1;
}
unlink(sunaddr.sun_path);
if (bind(lcconf->sock_admin, (struct sockaddr *)&sunaddr,
sizeof(sunaddr)) != 0) {
plog(LLV_ERROR, LOCATION, NULL,
"bind(sockname:%s): %s\n",
sunaddr.sun_path, strerror(errno));
(void)close(lcconf->sock_admin);
return -1;
}
if (chown(sunaddr.sun_path, adminsock_owner, adminsock_group) != 0) {
plog(LLV_ERROR, LOCATION, NULL,
"chown(%s, %d, %d): %s\n",
sunaddr.sun_path, adminsock_owner,
adminsock_group, strerror(errno));
(void)close(lcconf->sock_admin);
return -1;
}
if (chmod(sunaddr.sun_path, adminsock_mode) != 0) {
plog(LLV_ERROR, LOCATION, NULL,
"chmod(%s, 0%03o): %s\n",
sunaddr.sun_path, adminsock_mode, strerror(errno));
(void)close(lcconf->sock_admin);
return -1;
}
if (listen(lcconf->sock_admin, 5) != 0) {
plog(LLV_ERROR, LOCATION, NULL,
"listen(sockname:%s): %s\n",
sunaddr.sun_path, strerror(errno));
(void)close(lcconf->sock_admin);
return -1;
}
plog(LLV_DEBUG, LOCATION, NULL,
"open %s as racoon management.\n", sunaddr.sun_path);
return 0;
}
int
admin_close()
{
close(lcconf->sock_admin);
return 0;
}
#endif
static void
isakmp_flush_sa(iph1, loc, rem)
struct ph1handle *iph1;
char *loc;
char *rem;
{
plog(LLV_INFO, LOCATION, NULL,
"Flushing SA for %s -> %s\n", loc, rem);
if (iph1->status == PHASE1ST_ESTABLISHED)
isakmp_info_send_d1(iph1);
remph1(iph1);
delph1(iph1);
return;
}

View File

@ -0,0 +1,107 @@
/* $Id: admin.h,v 1.1.1.1 2005/02/12 11:11:38 manu Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#ifndef _ADMIN_H
#define _ADMIN_H
#define ADMINSOCK_PATH ADMINPORTDIR "/racoon.sock"
extern char *adminsock_path;
extern uid_t adminsock_owner;
extern gid_t adminsock_group;
extern mode_t adminsock_mode;
/* command for administration. */
/* NOTE: host byte order. */
struct admin_com {
u_int16_t ac_len; /* total packet length including data */
u_int16_t ac_cmd;
int16_t ac_errno;
u_int16_t ac_proto;
};
/*
* No data follows as the data.
* These don't use proto field.
*/
#define ADMIN_RELOAD_CONF 0x0001
#define ADMIN_SHOW_SCHED 0x0002
#define ADMIN_SHOW_EVT 0x0003
/*
* No data follows as the data.
* These use proto field.
*/
#define ADMIN_SHOW_SA 0x0101
#define ADMIN_FLUSH_SA 0x0102
/*
* The admin_com_indexes follows, see below.
*/
#define ADMIN_DELETE_SA 0x0201
#define ADMIN_ESTABLISH_SA 0x0202
#define ADMIN_DELETE_ALL_SA_DST 0x0204 /* All SA for a given peer */
/*
* The admin_com_indexes and admin_com_psk follow, see below.
*/
#define ADMIN_ESTABLISH_SA_PSK 0x0203
/*
* Range 0x08xx is reserved for privilege separation, see privsep.h
*/
/* the value of proto */
#define ADMIN_PROTO_ISAKMP 0x01ff
#define ADMIN_PROTO_IPSEC 0x02ff
#define ADMIN_PROTO_AH 0x0201
#define ADMIN_PROTO_ESP 0x0202
#define ADMIN_PROTO_INTERNAL 0x0301
struct admin_com_indexes {
u_int8_t prefs;
u_int8_t prefd;
u_int8_t ul_proto;
u_int8_t reserved;
struct sockaddr_storage src;
struct sockaddr_storage dst;
};
struct admin_com_psk {
int id_type;
size_t id_len;
size_t key_len;
/* Followed by id and key */
};
extern int admin2pfkey_proto __P((u_int));
#endif /* _ADMIN_H */

View File

@ -0,0 +1,39 @@
/* $Id: admin_var.h,v 1.1.1.1 2005/02/12 11:11:38 manu Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#ifndef _ADMIN_VAR_H
#define _ADMIN_VAR_H
extern int admin_handler __P((void));
extern int admin_init __P((void));
extern int admin_close __P((void));
#endif /* _ADMIN_VAR_H */

View File

@ -0,0 +1,915 @@
/* $Id: algorithm.c,v 1.1.1.1 2005/02/12 11:11:39 manu Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#include "config.h"
#include <sys/param.h>
#include <sys/types.h>
#include <stdlib.h>
#include "var.h"
#include "misc.h"
#include "vmbuf.h"
#include "plog.h"
#include "debug.h"
#include "crypto_openssl.h"
#include "dhgroup.h"
#include "algorithm.h"
#include "oakley.h"
#include "isakmp_var.h"
#include "isakmp.h"
#include "ipsec_doi.h"
#include "gcmalloc.h"
static struct hash_algorithm oakley_hashdef[] = {
{ "md5", algtype_md5, OAKLEY_ATTR_HASH_ALG_MD5,
eay_md5_init, eay_md5_update,
eay_md5_final, eay_md5_hashlen,
eay_md5_one, },
{ "sha1", algtype_sha1, OAKLEY_ATTR_HASH_ALG_SHA,
eay_sha1_init, eay_sha1_update,
eay_sha1_final, eay_sha1_hashlen,
eay_sha1_one, },
#ifdef WITH_SHA2
{ "sha2_256", algtype_sha2_256, OAKLEY_ATTR_HASH_ALG_SHA2_256,
eay_sha2_256_init, eay_sha2_256_update,
eay_sha2_256_final, eay_sha2_256_hashlen,
eay_sha2_256_one, },
{ "sha2_384", algtype_sha2_384, OAKLEY_ATTR_HASH_ALG_SHA2_384,
eay_sha2_384_init, eay_sha2_384_update,
eay_sha2_384_final, eay_sha2_384_hashlen,
eay_sha2_384_one, },
{ "sha2_512", algtype_sha2_512, OAKLEY_ATTR_HASH_ALG_SHA2_512,
eay_sha2_512_init, eay_sha2_512_update,
eay_sha2_512_final, eay_sha2_512_hashlen,
eay_sha2_512_one, },
#endif
};
static struct hmac_algorithm oakley_hmacdef[] = {
{ "hmac_md5", algtype_md5, OAKLEY_ATTR_HASH_ALG_MD5,
eay_hmacmd5_init, eay_hmacmd5_update,
eay_hmacmd5_final, NULL,
eay_hmacmd5_one, },
{ "hmac_sha1", algtype_sha1, OAKLEY_ATTR_HASH_ALG_SHA,
eay_hmacsha1_init, eay_hmacsha1_update,
eay_hmacsha1_final, NULL,
eay_hmacsha1_one, },
#ifdef WITH_SHA2
{ "hmac_sha2_256", algtype_sha2_256, OAKLEY_ATTR_HASH_ALG_SHA2_256,
eay_hmacsha2_256_init, eay_hmacsha2_256_update,
eay_hmacsha2_256_final, NULL,
eay_hmacsha2_256_one, },
{ "hmac_sha2_384", algtype_sha2_384, OAKLEY_ATTR_HASH_ALG_SHA2_384,
eay_hmacsha2_384_init, eay_hmacsha2_384_update,
eay_hmacsha2_384_final, NULL,
eay_hmacsha2_384_one, },
{ "hmac_sha2_512", algtype_sha2_512, OAKLEY_ATTR_HASH_ALG_SHA2_512,
eay_hmacsha2_512_init, eay_hmacsha2_512_update,
eay_hmacsha2_512_final, NULL,
eay_hmacsha2_512_one, },
#endif
};
static struct enc_algorithm oakley_encdef[] = {
{ "des", algtype_des, OAKLEY_ATTR_ENC_ALG_DES, 8,
eay_des_encrypt, eay_des_decrypt,
eay_des_weakkey, eay_des_keylen, },
#ifdef HAVE_OPENSSL_IDEA_H
{ "idea", algtype_idea, OAKLEY_ATTR_ENC_ALG_IDEA, 8,
eay_idea_encrypt, eay_idea_decrypt,
eay_idea_weakkey, eay_idea_keylen, },
#endif
{ "blowfish", algtype_blowfish, OAKLEY_ATTR_ENC_ALG_BLOWFISH, 8,
eay_bf_encrypt, eay_bf_decrypt,
eay_bf_weakkey, eay_bf_keylen, },
#ifdef HAVE_OPENSSL_RC5_H
{ "rc5", algtype_rc5, OAKLEY_ATTR_ENC_ALG_RC5, 8,
eay_rc5_encrypt, eay_rc5_decrypt,
eay_rc5_weakkey, eay_rc5_keylen, },
#endif
{ "3des", algtype_3des, OAKLEY_ATTR_ENC_ALG_3DES, 8,
eay_3des_encrypt, eay_3des_decrypt,
eay_3des_weakkey, eay_3des_keylen, },
{ "cast", algtype_cast128, OAKLEY_ATTR_ENC_ALG_CAST, 8,
eay_cast_encrypt, eay_cast_decrypt,
eay_cast_weakkey, eay_cast_keylen, },
{ "aes", algtype_aes, OAKLEY_ATTR_ENC_ALG_AES, 16,
eay_aes_encrypt, eay_aes_decrypt,
eay_aes_weakkey, eay_aes_keylen, },
};
static struct enc_algorithm ipsec_encdef[] = {
{ "des-iv64", algtype_des_iv64, IPSECDOI_ESP_DES_IV64, 8,
NULL, NULL,
NULL, eay_des_keylen, },
{ "des", algtype_des, IPSECDOI_ESP_DES, 8,
NULL, NULL,
NULL, eay_des_keylen, },
{ "3des", algtype_3des, IPSECDOI_ESP_3DES, 8,
NULL, NULL,
NULL, eay_3des_keylen, },
#ifdef HAVE_OPENSSL_RC5_H
{ "rc5", algtype_rc5, IPSECDOI_ESP_RC5, 8,
NULL, NULL,
NULL, eay_rc5_keylen, },
#endif
{ "cast", algtype_cast128, IPSECDOI_ESP_CAST, 8,
NULL, NULL,
NULL, eay_cast_keylen, },
{ "blowfish", algtype_blowfish, IPSECDOI_ESP_BLOWFISH, 8,
NULL, NULL,
NULL, eay_bf_keylen, },
{ "des-iv32", algtype_des_iv32, IPSECDOI_ESP_DES_IV32, 8,
NULL, NULL,
NULL, eay_des_keylen, },
{ "null", algtype_null_enc, IPSECDOI_ESP_NULL, 8,
NULL, NULL,
NULL, eay_null_keylen, },
{ "aes", algtype_aes, IPSECDOI_ESP_AES, 16,
NULL, NULL,
NULL, eay_aes_keylen, },
{ "twofish", algtype_twofish, IPSECDOI_ESP_TWOFISH, 16,
NULL, NULL,
NULL, eay_twofish_keylen, },
#ifdef HAVE_OPENSSL_IDEA_H
{ "3idea", algtype_3idea, IPSECDOI_ESP_3IDEA, 8,
NULL, NULL,
NULL, NULL, },
{ "idea", algtype_idea, IPSECDOI_ESP_IDEA, 8,
NULL, NULL,
NULL, NULL, },
#endif
{ "rc4", algtype_rc4, IPSECDOI_ESP_RC4, 8,
NULL, NULL,
NULL, NULL, },
};
static struct hmac_algorithm ipsec_hmacdef[] = {
{ "md5", algtype_hmac_md5, IPSECDOI_ATTR_AUTH_HMAC_MD5,
NULL, NULL,
NULL, eay_md5_hashlen,
NULL, },
{ "sha1", algtype_hmac_sha1, IPSECDOI_ATTR_AUTH_HMAC_SHA1,
NULL, NULL,
NULL, eay_sha1_hashlen,
NULL, },
{ "kpdk", algtype_kpdk, IPSECDOI_ATTR_AUTH_KPDK,
NULL, NULL,
NULL, eay_kpdk_hashlen,
NULL, },
{ "null", algtype_non_auth, IPSECDOI_ATTR_AUTH_NONE,
NULL, NULL,
NULL, eay_null_hashlen,
NULL, },
#ifdef WITH_SHA2
{ "hmac_sha2_256", algtype_hmac_sha2_256, IPSECDOI_ATTR_SHA2_256,
NULL, NULL,
NULL, eay_sha2_256_hashlen,
NULL, },
{ "hmac_sha2_384", algtype_hmac_sha2_384, IPSECDOI_ATTR_SHA2_384,
NULL, NULL,
NULL, eay_sha2_384_hashlen,
NULL, },
{ "hmac_sha2_512", algtype_hmac_sha2_512, IPSECDOI_ATTR_SHA2_512,
NULL, NULL,
NULL, eay_sha2_512_hashlen,
NULL, },
#endif
};
static struct misc_algorithm ipsec_compdef[] = {
{ "oui", algtype_oui, IPSECDOI_IPCOMP_OUI, },
{ "deflate", algtype_deflate, IPSECDOI_IPCOMP_DEFLATE, },
{ "lzs", algtype_lzs, IPSECDOI_IPCOMP_LZS, },
};
static struct misc_algorithm oakley_authdef[] = {
{ "pre_shared_key", algtype_psk, OAKLEY_ATTR_AUTH_METHOD_PSKEY, },
{ "dsssig", algtype_dsssig, OAKLEY_ATTR_AUTH_METHOD_DSSSIG, },
{ "rsasig", algtype_rsasig, OAKLEY_ATTR_AUTH_METHOD_RSASIG, },
{ "rsaenc", algtype_rsaenc, OAKLEY_ATTR_AUTH_METHOD_RSAENC, },
{ "rsarev", algtype_rsarev, OAKLEY_ATTR_AUTH_METHOD_RSAREV, },
{ "gssapi_krb", algtype_gssapikrb, OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB, },
#ifdef ENABLE_HYBRID
{ "hybrid_rsa_server", algtype_hybrid_rsa_s,
OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I, },
{ "hybrid_dss_server", algtype_hybrid_dss_s,
OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I, },
{ "hybrid_rsa_client", algtype_hybrid_rsa_c,
OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R, },
{ "hybrid_dss_client", algtype_hybrid_dss_c,
OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R, },
#endif
};
static struct dh_algorithm oakley_dhdef[] = {
{ "modp768", algtype_modp768, OAKLEY_ATTR_GRP_DESC_MODP768,
&dh_modp768, },
{ "modp1024", algtype_modp1024, OAKLEY_ATTR_GRP_DESC_MODP1024,
&dh_modp1024, },
{ "modp1536", algtype_modp1536, OAKLEY_ATTR_GRP_DESC_MODP1536,
&dh_modp1536, },
{ "modp2048", algtype_modp2048, OAKLEY_ATTR_GRP_DESC_MODP2048,
&dh_modp2048, },
{ "modp3072", algtype_modp3072, OAKLEY_ATTR_GRP_DESC_MODP3072,
&dh_modp3072, },
{ "modp4096", algtype_modp4096, OAKLEY_ATTR_GRP_DESC_MODP4096,
&dh_modp4096, },
{ "modp6144", algtype_modp6144, OAKLEY_ATTR_GRP_DESC_MODP6144,
&dh_modp6144, },
{ "modp8192", algtype_modp8192, OAKLEY_ATTR_GRP_DESC_MODP8192,
&dh_modp8192, },
};
static struct hash_algorithm *alg_oakley_hashdef __P((int));
static struct hmac_algorithm *alg_oakley_hmacdef __P((int));
static struct enc_algorithm *alg_oakley_encdef __P((int));
static struct enc_algorithm *alg_ipsec_encdef __P((int));
static struct hmac_algorithm *alg_ipsec_hmacdef __P((int));
static struct dh_algorithm *alg_oakley_dhdef __P((int));
/* oakley hash algorithm */
static struct hash_algorithm *
alg_oakley_hashdef(doi)
int doi;
{
int i;
for (i = 0; i < ARRAYLEN(oakley_hashdef); i++)
if (doi == oakley_hashdef[i].doi) {
plog(LLV_DEBUG, LOCATION, NULL, "hash(%s)\n",
oakley_hashdef[i].name);
return &oakley_hashdef[i];
}
return NULL;
}
int
alg_oakley_hashdef_ok(doi)
int doi;
{
struct hash_algorithm *f;
f = alg_oakley_hashdef(doi);
if (f == NULL)
return 0;
return 1;
}
int
alg_oakley_hashdef_doi(type)
int type;
{
int i, res = -1;
for (i = 0; i < ARRAYLEN(oakley_hashdef); i++)
if (type == oakley_hashdef[i].type) {
res = oakley_hashdef[i].doi;
break;
}
return res;
}
int
alg_oakley_hashdef_hashlen(doi)
int doi;
{
struct hash_algorithm *f;
f = alg_oakley_hashdef(doi);
if (f == NULL || f->hashlen == NULL)
return 0;
return (f->hashlen)();
}
const char *
alg_oakley_hashdef_name (doi)
int doi;
{
struct hash_algorithm *f;
f = alg_oakley_hashdef(doi);
if (f == NULL)
return "*UNKNOWN*";
return f->name;
}
vchar_t *
alg_oakley_hashdef_one(doi, buf)
int doi;
vchar_t *buf;
{
struct hash_algorithm *f;
f = alg_oakley_hashdef(doi);
if (f == NULL || f->hashlen == NULL)
return NULL;
return (f->one)(buf);
}
/* oakley hmac algorithm */
static struct hmac_algorithm *
alg_oakley_hmacdef(doi)
int doi;
{
int i;
for (i = 0; i < ARRAYLEN(oakley_hmacdef); i++)
if (doi == oakley_hmacdef[i].doi) {
plog(LLV_DEBUG, LOCATION, NULL, "hmac(%s)\n",
oakley_hmacdef[i].name);
return &oakley_hmacdef[i];
}
return NULL;
}
int
alg_oakley_hmacdef_doi(type)
int type;
{
int i, res = -1;
for (i = 0; i < ARRAYLEN(oakley_hmacdef); i++)
if (type == oakley_hmacdef[i].type) {
res = oakley_hmacdef[i].doi;
break;
}
return res;
}
vchar_t *
alg_oakley_hmacdef_one(doi, key, buf)
int doi;
vchar_t *key, *buf;
{
struct hmac_algorithm *f;
vchar_t *res;
#ifdef ENABLE_STATS
struct timeval start, end;
#endif
f = alg_oakley_hmacdef(doi);
if (f == NULL || f->one == NULL)
return NULL;
#ifdef ENABLE_STATS
gettimeofday(&start, NULL);
#endif
res = (f->one)(key, buf);
#ifdef ENABLE_STATS
gettimeofday(&end, NULL);
syslog(LOG_NOTICE, "%s(%s size=%d): %8.6f", __func__,
f->name, buf->l, timedelta(&start, &end));
#endif
return res;
}
/* oakley encryption algorithm */
static struct enc_algorithm *
alg_oakley_encdef(doi)
int doi;
{
int i;
for (i = 0; i < ARRAYLEN(oakley_encdef); i++)
if (doi == oakley_encdef[i].doi) {
plog(LLV_DEBUG, LOCATION, NULL, "encryption(%s)\n",
oakley_encdef[i].name);
return &oakley_encdef[i];
}
return NULL;
}
int
alg_oakley_encdef_ok(doi)
int doi;
{
struct enc_algorithm *f;
f = alg_oakley_encdef(doi);
if (f == NULL)
return 0;
return 1;
}
int
alg_oakley_encdef_doi(type)
int type;
{
int i, res = -1;
for (i = 0; i < ARRAYLEN(oakley_encdef); i++)
if (type == oakley_encdef[i].type) {
res = oakley_encdef[i].doi;
break;
}
return res;
}
int
alg_oakley_encdef_keylen(doi, len)
int doi, len;
{
struct enc_algorithm *f;
f = alg_oakley_encdef(doi);
if (f == NULL || f->keylen == NULL)
return -1;
return (f->keylen)(len);
}
int
alg_oakley_encdef_blocklen(doi)
int doi;
{
struct enc_algorithm *f;
f = alg_oakley_encdef(doi);
if (f == NULL)
return -1;
return f->blocklen;
}
const char *
alg_oakley_encdef_name (doi)
int doi;
{
struct enc_algorithm *f;
f = alg_oakley_encdef(doi);
if (f == NULL)
return "*UNKNOWN*";
return f->name;
}
vchar_t *
alg_oakley_encdef_decrypt(doi, buf, key, iv)
int doi;
vchar_t *buf, *key, *iv;
{
vchar_t *res;
struct enc_algorithm *f;
#ifdef ENABLE_STATS
struct timeval start, end;
#endif
f = alg_oakley_encdef(doi);
if (f == NULL || f->decrypt == NULL)
return NULL;
#ifdef ENABLE_STATS
gettimeofday(&start, NULL);
#endif
res = (f->decrypt)(buf, key, iv);
#ifdef ENABLE_STATS
gettimeofday(&end, NULL);
syslog(LOG_NOTICE, "%s(%s klen=%d size=%d): %8.6f", __func__,
f->name, key->l << 3, buf->l, timedelta(&start, &end));
#endif
return res;
}
vchar_t *
alg_oakley_encdef_encrypt(doi, buf, key, iv)
int doi;
vchar_t *buf, *key, *iv;
{
vchar_t *res;
struct enc_algorithm *f;
#ifdef ENABLE_STATS
struct timeval start, end;
#endif
f = alg_oakley_encdef(doi);
if (f == NULL || f->encrypt == NULL)
return NULL;
#ifdef ENABLE_STATS
gettimeofday(&start, NULL);
#endif
res = (f->encrypt)(buf, key, iv);
#ifdef ENABLE_STATS
gettimeofday(&end, NULL);
syslog(LOG_NOTICE, "%s(%s klen=%d size=%d): %8.6f", __func__,
f->name, key->l << 3, buf->l, timedelta(&start, &end));
#endif
return res;
}
/* ipsec encryption algorithm */
static struct enc_algorithm *
alg_ipsec_encdef(doi)
int doi;
{
int i;
for (i = 0; i < ARRAYLEN(ipsec_encdef); i++)
if (doi == ipsec_encdef[i].doi) {
plog(LLV_DEBUG, LOCATION, NULL, "encryption(%s)\n",
ipsec_encdef[i].name);
return &ipsec_encdef[i];
}
return NULL;
}
int
alg_ipsec_encdef_doi(type)
int type;
{
int i, res = -1;
for (i = 0; i < ARRAYLEN(ipsec_encdef); i++)
if (type == ipsec_encdef[i].type) {
res = ipsec_encdef[i].doi;
break;
}
return res;
}
int
alg_ipsec_encdef_keylen(doi, len)
int doi, len;
{
struct enc_algorithm *f;
f = alg_ipsec_encdef(doi);
if (f == NULL || f->keylen == NULL)
return -1;
return (f->keylen)(len);
}
/* ipsec hmac algorithm */
static struct hmac_algorithm *
alg_ipsec_hmacdef(doi)
int doi;
{
int i;
for (i = 0; i < ARRAYLEN(ipsec_hmacdef); i++)
if (doi == ipsec_hmacdef[i].doi) {
plog(LLV_DEBUG, LOCATION, NULL, "hmac(%s)\n",
oakley_hmacdef[i].name);
return &ipsec_hmacdef[i];
}
return NULL;
}
int
alg_ipsec_hmacdef_doi(type)
int type;
{
int i, res = -1;
for (i = 0; i < ARRAYLEN(ipsec_hmacdef); i++)
if (type == ipsec_hmacdef[i].type) {
res = ipsec_hmacdef[i].doi;
break;
}
return res;
}
int
alg_ipsec_hmacdef_hashlen(doi)
int doi;
{
struct hmac_algorithm *f;
f = alg_ipsec_hmacdef(doi);
if (f == NULL || f->hashlen == NULL)
return -1;
return (f->hashlen)();
}
/* ip compression */
int
alg_ipsec_compdef_doi(type)
int type;
{
int i, res = -1;
for (i = 0; i < ARRAYLEN(ipsec_compdef); i++)
if (type == ipsec_compdef[i].type) {
res = ipsec_compdef[i].doi;
break;
}
return res;
}
/* dh algorithm */
static struct dh_algorithm *
alg_oakley_dhdef(doi)
int doi;
{
int i;
for (i = 0; i < ARRAYLEN(oakley_dhdef); i++)
if (doi == oakley_dhdef[i].doi) {
plog(LLV_DEBUG, LOCATION, NULL, "hmac(%s)\n",
oakley_dhdef[i].name);
return &oakley_dhdef[i];
}
return NULL;
}
int
alg_oakley_dhdef_ok(doi)
int doi;
{
struct dh_algorithm *f;
f = alg_oakley_dhdef(doi);
if (f == NULL)
return 0;
return 1;
}
int
alg_oakley_dhdef_doi(type)
int type;
{
int i, res = -1;
for (i = 0; i < ARRAYLEN(oakley_dhdef); i++)
if (type == oakley_dhdef[i].type) {
res = oakley_dhdef[i].doi;
break;
}
return res;
}
struct dhgroup *
alg_oakley_dhdef_group(doi)
int doi;
{
struct dh_algorithm *f;
f = alg_oakley_dhdef(doi);
if (f == NULL || f->dhgroup == NULL)
return NULL;
return f->dhgroup;
}
const char *
alg_oakley_dhdef_name (doi)
int doi;
{
struct dh_algorithm *f;
f = alg_oakley_dhdef(doi);
if (f == NULL)
return "*UNKNOWN*";
return f->name;
}
/* authentication method */
int
alg_oakley_authdef_doi(type)
int type;
{
int i, res = -1;
for (i = 0; i < ARRAYLEN(oakley_authdef); i++)
if (type == oakley_authdef[i].type) {
res = oakley_authdef[i].doi;
break;
}
return res;
}
const char *
alg_oakley_authdef_name (doi)
int doi;
{
int i;
for (i = 0; i < ARRAYLEN(oakley_authdef); i++)
if (doi == oakley_authdef[i].doi) {
return oakley_authdef[i].name;
}
return "*UNKNOWN*";
}
/*
* give the default key length
* OUT: -1: NG
* 0: fixed key cipher, key length not allowed
* positive: default key length
*/
int
default_keylen(class, type)
int class, type;
{
switch (class) {
case algclass_isakmp_enc:
case algclass_ipsec_enc:
break;
default:
return 0;
}
switch (type) {
case algtype_blowfish:
case algtype_rc5:
case algtype_cast128:
case algtype_aes:
case algtype_twofish:
return 128;
default:
return 0;
}
}
/*
* check key length
* OUT: -1: NG
* 0: OK
*/
int
check_keylen(class, type, len)
int class, type, len;
{
int badrange;
switch (class) {
case algclass_isakmp_enc:
case algclass_ipsec_enc:
break;
default:
/* unknown class, punt */
plog(LLV_ERROR, LOCATION, NULL,
"unknown algclass %d\n", class);
return -1;
}
/* key length must be multiple of 8 bytes - RFC2451 2.2 */
switch (type) {
case algtype_blowfish:
case algtype_rc5:
case algtype_cast128:
case algtype_aes:
case algtype_twofish:
if (len % 8 != 0) {
plog(LLV_ERROR, LOCATION, NULL,
"key length %d is not multiple of 8\n", len);
return -1;
}
break;
}
/* key length range */
badrange = 0;
switch (type) {
case algtype_blowfish:
if (len < 40 || 448 < len)
badrange++;
break;
case algtype_rc5:
if (len < 40 || 2040 < len)
badrange++;
break;
case algtype_cast128:
if (len < 40 || 128 < len)
badrange++;
break;
case algtype_aes:
if (!(len == 128 || len == 192 || len == 256))
badrange++;
break;
case algtype_twofish:
if (len < 40 || 256 < len)
badrange++;
break;
default:
if (len) {
plog(LLV_ERROR, LOCATION, NULL,
"key length is not allowed");
return -1;
}
break;
}
if (badrange) {
plog(LLV_ERROR, LOCATION, NULL,
"key length out of range\n");
return -1;
}
return 0;
}
/*
* convert algorithm type to DOI value.
* OUT -1 : NG
* other: converted.
*/
int
algtype2doi(class, type)
int class, type;
{
int res = -1;
switch (class) {
case algclass_ipsec_enc:
res = alg_ipsec_encdef_doi(type);
break;
case algclass_ipsec_auth:
res = alg_ipsec_hmacdef_doi(type);
break;
case algclass_ipsec_comp:
res = alg_ipsec_compdef_doi(type);
break;
case algclass_isakmp_enc:
res = alg_oakley_encdef_doi(type);
break;
case algclass_isakmp_hash:
res = alg_oakley_hashdef_doi(type);
break;
case algclass_isakmp_dh:
res = alg_oakley_dhdef_doi(type);
break;
case algclass_isakmp_ameth:
res = alg_oakley_authdef_doi(type);
break;
}
return res;
}
/*
* convert algorithm class to DOI value.
* OUT -1 : NG
* other: converted.
*/
int
algclass2doi(class)
int class;
{
switch (class) {
case algclass_ipsec_enc:
return IPSECDOI_PROTO_IPSEC_ESP;
case algclass_ipsec_auth:
return IPSECDOI_ATTR_AUTH;
case algclass_ipsec_comp:
return IPSECDOI_PROTO_IPCOMP;
case algclass_isakmp_enc:
return OAKLEY_ATTR_ENC_ALG;
case algclass_isakmp_hash:
return OAKLEY_ATTR_HASH_ALG;
case algclass_isakmp_dh:
return OAKLEY_ATTR_GRP_DESC;
case algclass_isakmp_ameth:
return OAKLEY_ATTR_AUTH_METHOD;
default:
return -1;
}
/*NOTREACHED*/
return -1;
}

View File

@ -0,0 +1,209 @@
/* $Id: algorithm.h,v 1.1.1.1 2005/02/12 11:11:40 manu Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#ifndef _ALGORITHM_H
#define _ALGORITHM_H
#include <gnuc.h>
/* algorithm class */
enum {
algclass_ipsec_enc,
algclass_ipsec_auth,
algclass_ipsec_comp,
algclass_isakmp_enc,
algclass_isakmp_hash,
algclass_isakmp_dh,
algclass_isakmp_ameth, /* authentication method. */
#define MAXALGCLASS 7
};
#define ALG_DEFAULT_KEYLEN 64
#define ALGTYPE_NOTHING 0
/* algorithm type */
enum algtype {
algtype_nothing = 0,
/* enc */
algtype_des_iv64,
algtype_des,
algtype_3des,
algtype_rc5,
algtype_idea,
algtype_cast128,
algtype_blowfish,
algtype_3idea,
algtype_des_iv32,
algtype_rc4,
algtype_null_enc,
algtype_aes,
algtype_twofish,
/* ipsec auth */
algtype_hmac_md5,
algtype_hmac_sha1,
algtype_des_mac,
algtype_kpdk,
algtype_non_auth,
algtype_hmac_sha2_256,
algtype_hmac_sha2_384,
algtype_hmac_sha2_512,
/* ipcomp */
algtype_oui,
algtype_deflate,
algtype_lzs,
/* hash */
algtype_md5,
algtype_sha1,
algtype_tiger,
algtype_sha2_256,
algtype_sha2_384,
algtype_sha2_512,
/* dh_group */
algtype_modp768,
algtype_modp1024,
algtype_ec2n155,
algtype_ec2n185,
algtype_modp1536,
algtype_modp2048,
algtype_modp3072,
algtype_modp4096,
algtype_modp6144,
algtype_modp8192,
/* authentication method. */
algtype_psk,
algtype_dsssig,
algtype_rsasig,
algtype_rsaenc,
algtype_rsarev,
algtype_gssapikrb,
#ifdef ENABLE_HYBRID
algtype_hybrid_rsa_s,
algtype_hybrid_dss_s,
algtype_hybrid_rsa_c,
algtype_hybrid_dss_c,
#endif
};
struct hmac_algorithm {
char *name;
int type;
int doi;
caddr_t (*init) __P((vchar_t *));
void (*update) __P((caddr_t, vchar_t *));
vchar_t *(*final) __P((caddr_t));
int (*hashlen) __P((void));
vchar_t *(*one) __P((vchar_t *, vchar_t *));
};
struct hash_algorithm {
char *name;
int type;
int doi;
caddr_t (*init) __P((void));
void (*update) __P((caddr_t, vchar_t *));
vchar_t *(*final) __P((caddr_t));
int (*hashlen) __P((void));
vchar_t *(*one) __P((vchar_t *));
};
struct enc_algorithm {
char *name;
int type;
int doi;
int blocklen;
vchar_t *(*encrypt) __P((vchar_t *, vchar_t *, vchar_t *));
vchar_t *(*decrypt) __P((vchar_t *, vchar_t *, vchar_t *));
int (*weakkey) __P((vchar_t *));
int (*keylen) __P((int));
};
/* dh group */
struct dh_algorithm {
char *name;
int type;
int doi;
struct dhgroup *dhgroup;
};
/* ipcomp, auth meth, dh group */
struct misc_algorithm {
char *name;
int type;
int doi;
};
extern int alg_oakley_hashdef_ok __P((int));
extern int alg_oakley_hashdef_doi __P((int));
extern int alg_oakley_hashdef_hashlen __P((int));
extern vchar_t *alg_oakley_hashdef_one __P((int, vchar_t *));
extern int alg_oakley_hmacdef_doi __P((int));
extern vchar_t *alg_oakley_hmacdef_one __P((int, vchar_t *, vchar_t *));
extern int alg_oakley_encdef_ok __P((int));
extern int alg_oakley_encdef_doi __P((int));
extern int alg_oakley_encdef_keylen __P((int, int));
extern int alg_oakley_encdef_blocklen __P((int));
extern vchar_t *alg_oakley_encdef_decrypt __P((int, vchar_t *, vchar_t *, vchar_t *));
extern vchar_t *alg_oakley_encdef_encrypt __P((int, vchar_t *, vchar_t *, vchar_t *));
extern int alg_ipsec_encdef_doi __P((int));
extern int alg_ipsec_encdef_keylen __P((int, int));
extern int alg_ipsec_hmacdef_doi __P((int));
extern int alg_ipsec_hmacdef_hashlen __P((int));
extern int alg_ipsec_compdef_doi __P((int));
extern int alg_oakley_dhdef_doi __P((int));
extern int alg_oakley_dhdef_ok __P((int));
extern struct dhgroup *alg_oakley_dhdef_group __P((int));
extern int alg_oakley_authdef_doi __P((int));
extern int default_keylen __P((int, int));
extern int check_keylen __P((int, int, int));
extern int algtype2doi __P((int, int));
extern int algclass2doi __P((int));
extern const char *alg_oakley_encdef_name __P((int));
extern const char *alg_oakley_hashdef_name __P((int));
extern const char *alg_oakley_dhdef_name __P((int));
extern const char *alg_oakley_authdef_name __P((int));
#endif /* _ALGORITHM_H */

View File

@ -0,0 +1,487 @@
/* $KAME: backupsa.c,v 1.16 2001/12/31 20:13:40 thorpej Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#include "config.h"
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <netinet/in.h>
#ifndef HAVE_NETINET6_IPSEC
#include <netinet/ipsec.h>
#else
#include <netinet6/ipsec.h>
#endif
#if TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# if HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
# endif
#endif
#include "var.h"
#include "misc.h"
#include "vmbuf.h"
#include "str2val.h"
#include "plog.h"
#include "debug.h"
#include "localconf.h"
#include "sockmisc.h"
#include "safefile.h"
#include "backupsa.h"
#include "libpfkey.h"
/*
* (time string)%(sa parameter)
* (time string) := ex. Nov 24 18:22:48 1986
* (sa parameter) :=
* src dst satype spi mode reqid wsize \
* e_type e_keylen a_type a_keylen flags \
* l_alloc l_bytes l_addtime l_usetime seq keymat
*/
static char *format = "%b %d %T %Y"; /* time format */
static char *strmon[12] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
static char *str2tmx __P((char *, struct tm *));
static int str2num __P((char *, int));
/*
* output the sa parameter.
*/
int
backupsa_to_file(satype, mode, src, dst, spi, reqid, wsize,
keymat, e_type, e_keylen, a_type, a_keylen, flags,
l_alloc, l_bytes, l_addtime, l_usetime, seq)
u_int satype, mode, wsize;
struct sockaddr *src, *dst;
u_int32_t spi, reqid;
caddr_t keymat;
u_int e_type, e_keylen, a_type, a_keylen, flags;
u_int32_t l_alloc;
u_int64_t l_bytes, l_addtime, l_usetime;
u_int32_t seq;
{
char buf[1024];
struct tm *tm;
time_t t;
char *p, *k;
int len, l, i;
FILE *fp;
p = buf;
len = sizeof(buf);
t = time(NULL);
tm = localtime(&t);
l = strftime(p, len, format, tm);
p += l;
len -= l;
if (len < 0)
goto err;
l = snprintf(p, len, "%%");
if (l < 0 || l >= len)
goto err;
p += l;
len -= l;
if (len < 0)
goto err;
i = getnameinfo(src, sysdep_sa_len(src), p, len, NULL, 0, NIFLAGS);
if (i != 0)
goto err;
l = strlen(p);
p += l;
len -= l;
if (len < 0)
goto err;
l = snprintf(p, len, " ");
if (l < 0 || l >= len)
goto err;
p += l;
len -= l;
if (len < 0)
goto err;
i = getnameinfo(dst, sysdep_sa_len(dst), p, len, NULL, 0, NIFLAGS);
if (i != 0)
goto err;
l = strlen(p);
p += l;
len -= l;
if (len < 0)
goto err;
l = snprintf(p, len,
" %u %lu %u %u %u "
"%u %u %u %u %u "
"%u %llu %llu %llu %u",
satype, (unsigned long)ntohl(spi), mode, reqid, wsize,
e_type, e_keylen, a_type, a_keylen, flags,
l_alloc, (unsigned long long)l_bytes,
(unsigned long long)l_addtime, (unsigned long long)l_usetime,
seq);
if (l < 0 || l >= len)
goto err;
p += l;
len -= l;
if (len < 0)
goto err;
k = val2str(keymat, e_keylen + a_keylen);
l = snprintf(p, len, " %s", k);
if (l < 0 || l >= len)
goto err;
racoon_free(k);
p += l;
len -= l;
if (len < 0)
goto err;
/* open the file and write the SA parameter */
if (safefile(lcconf->pathinfo[LC_PATHTYPE_BACKUPSA], 1) != 0 ||
(fp = fopen(lcconf->pathinfo[LC_PATHTYPE_BACKUPSA], "a")) == NULL) {
plog(LLV_ERROR, LOCATION, NULL,
"failed to open the backup file %s.\n",
lcconf->pathinfo[LC_PATHTYPE_BACKUPSA]);
return -1;
}
fprintf(fp, "%s\n", buf);
fclose(fp);
return 0;
err:
plog(LLV_ERROR, LOCATION, NULL,
"SA cannot be saved to a file.\n");
return -1;
}
int
backupsa_from_file()
{
FILE *fp;
char buf[512];
struct tm tm;
time_t created, current;
char *p, *q;
u_int satype, mode;
struct sockaddr *src, *dst;
u_int32_t spi, reqid;
caddr_t keymat;
size_t keymatlen;
u_int wsize, e_type, e_keylen, a_type, a_keylen, flags;
u_int32_t l_alloc;
u_int64_t l_bytes, l_addtime, l_usetime;
u_int32_t seq;
int line;
if (safefile(lcconf->pathinfo[LC_PATHTYPE_BACKUPSA], 1) == 0)
fp = fopen(lcconf->pathinfo[LC_PATHTYPE_BACKUPSA], "r");
else
fp = NULL;
if (fp == NULL) {
plog(LLV_ERROR, LOCATION, NULL,
"failed to open the backup file %s.\n",
lcconf->pathinfo[LC_PATHTYPE_BACKUPSA]);
return -1;
}
current = time(NULL);
for(line = 1; fgets(buf, sizeof(buf), fp) != NULL; line++) {
/* comment line */
if (buf[0] == '#')
continue;
memset(&tm, 0, sizeof(tm));
p = str2tmx(buf, &tm);
if (*p != '%') {
err:
plog(LLV_ERROR, LOCATION, NULL,
"illegal format line#%d in %s: %s\n",
line, lcconf->pathinfo[LC_PATHTYPE_BACKUPSA], buf);
continue;
}
created = mktime(&tm);
p++;
for (q = p; *q != '\0' && !isspace((int)*q); q++)
;
*q = '\0';
src = str2saddr(p, NULL);
if (src == NULL)
goto err;
p = q + 1;
for (q = p; *q != '\0' && !isspace((int)*q); q++)
;
*q = '\0';
dst = str2saddr(p, NULL);
if (dst == NULL) {
racoon_free(src);
goto err;
}
p = q + 1;
#define GETNEXTNUM(value, function) \
do { \
char *y; \
for (q = p; *q != '\0' && !isspace((int)*q); q++) \
; \
*q = '\0'; \
(value) = function(p, &y, 10); \
if ((value) == 0 && *y != '\0') \
goto err; \
p = q + 1; \
} while (0);
GETNEXTNUM(satype, strtoul);
GETNEXTNUM(spi, strtoul);
spi = ntohl(spi);
GETNEXTNUM(mode, strtoul);
GETNEXTNUM(reqid, strtoul);
GETNEXTNUM(wsize, strtoul);
GETNEXTNUM(e_type, strtoul);
GETNEXTNUM(e_keylen, strtoul);
GETNEXTNUM(a_type, strtoul);
GETNEXTNUM(a_keylen, strtoul);
GETNEXTNUM(flags, strtoul);
GETNEXTNUM(l_alloc, strtoul);
GETNEXTNUM(l_bytes, strtouq);
GETNEXTNUM(l_addtime, strtouq);
GETNEXTNUM(l_usetime, strtouq);
GETNEXTNUM(seq, strtoul);
#undef GETNEXTNUM
keymat = str2val(p, 16, &keymatlen);
if (keymat == NULL) {
plog(LLV_ERROR, LOCATION, NULL,
"illegal format(keymat) line#%d in %s: %s\n",
line, lcconf->pathinfo[LC_PATHTYPE_BACKUPSA], buf);
racoon_free(src);
racoon_free(dst);
continue;
}
if (created + l_addtime < current) {
plog(LLV_DEBUG, LOCATION, NULL,
"ignore this line#%d in %s due to expiration\n",
line, lcconf->pathinfo[LC_PATHTYPE_BACKUPSA]);
racoon_free(src);
racoon_free(dst);
racoon_free(keymat);
continue;
}
l_addtime -= current - created;
if (pfkey_send_add(
lcconf->sock_pfkey,
satype,
mode,
src,
dst,
spi,
reqid,
wsize,
keymat,
e_type, e_keylen, a_type, a_keylen, flags,
0, l_bytes, l_addtime, 0, seq) < 0) {
plog(LLV_ERROR, LOCATION, NULL,
"restore SA filed line#%d in %s: %s\n",
line, lcconf->pathinfo[LC_PATHTYPE_BACKUPSA], ipsec_strerror());
}
racoon_free(src);
racoon_free(dst);
racoon_free(keymat);
}
fclose(fp);
/*
* There is a possibility that an abnormal system down will happen
* again before new negotiation will be started. so racoon clears
* the backup file here. it's ok that old SAs are remained in the
* file. any old SA will not be installed because racoon checks the
* lifetime and compare with current time.
*/
return 0;
}
int
backupsa_clean()
{
FILE *fp;
/* simply return if the file is not defined. */
if (!lcconf->pathinfo[LC_PATHTYPE_BACKUPSA])
return 0;
fp = fopen(lcconf->pathinfo[LC_PATHTYPE_BACKUPSA], "w+");
if (fp == NULL) {
plog(LLV_ERROR, LOCATION, NULL,
"failed to clean the backup file %s.\n",
lcconf->pathinfo[LC_PATHTYPE_BACKUPSA]);
return -1;
}
fclose(fp);
return 0;
}
/*
* convert fixed string into the tm structure.
* The fixed string is like 'Nov 24 18:22:48 1986'.
* static char *format = "%b %d %T %Y";
*/
static char *
str2tmx(char *p, struct tm *tm)
{
int i, len;
/* Month */
for (i = 0; i < sizeof(strmon)/sizeof(strmon[0]); i++) {
if (strncasecmp(p, strmon[i], strlen(strmon[i])) == 0) {
tm->tm_mon = i;
break;
}
}
if (i == sizeof(strmon)/sizeof(strmon[0]))
return 0;
p += strlen(strmon[i]);
if (*p++ != ' ')
return 0;
/* Day */
len = 2;
tm->tm_mday = str2num(p, len);
if (tm->tm_mday == -1 || tm->tm_mday > 31)
return 0;
p += len;
if (*p++ != ' ')
return 0;
/* Hour */
len = 2;
tm->tm_hour = str2num(p, len);
if (tm->tm_hour == -1 || tm->tm_hour > 24)
return 0;
p += len;
if (*p++ != ':')
return 0;
/* Min */
len = 2;
tm->tm_min = str2num(p, len);
if (tm->tm_min == -1 || tm->tm_min > 60)
return 0;
p += len;
if (*p++ != ':')
return 0;
/* Sec */
len = 2;
tm->tm_sec = str2num(p, len);
if (tm->tm_sec == -1 || tm->tm_sec > 60)
return 0;
p += len;
if (*p++ != ' ')
return 0;
/* Year */
len = 4;
tm->tm_year = str2num(p, len);
if (tm->tm_year == -1 || tm->tm_year < 1900)
return 0;
tm->tm_year -= 1900;
p += len;
return p;
}
static int
str2num(p, len)
char *p;
int len;
{
int res, i;
res = 0;
for (i = len; i > 0; i--) {
if (!isdigit((int)*p))
return -1;
res *= 10;
res += *p - '0';
p++;
}
return res;
}
#ifdef TEST
#include <stdio.h>
int
main()
{
struct tm tm;
time_t t;
char *buf = "Nov 24 18:22:48 1986 ";
char *p;
memset(&tm, 0, sizeof(tm));
p = str2tmx(buf, &tm);
printf("[%x]\n", *p);
t = mktime(&tm);
if (t == -1)
printf("mktime failed.");
p = ctime(&t);
printf("[%s]\n", p);
exit(0);
}
#endif

View File

@ -0,0 +1,42 @@
/* $Id: backupsa.h,v 1.1.1.1 2005/02/12 11:11:40 manu Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#ifndef _BACKUPSA_H
#define _BACKUPSA_H
extern int backupsa_to_file __P((u_int, u_int,
struct sockaddr *, struct sockaddr *, u_int32_t, u_int32_t, u_int,
caddr_t, u_int, u_int, u_int, u_int, u_int,
u_int32_t, u_int64_t, u_int64_t, u_int64_t, u_int32_t));
extern int backupsa_from_file __P((void));
extern int backupsa_clean __P((void));
#endif /* _BACKUPSA_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,40 @@
/* $Id: cfparse_proto.h,v 1.1.1.1 2005/02/12 11:11:36 manu Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#ifndef _CFPARSE_PROTO_H
#define _CFPARSE_PROTO_H
/* cfparse.y */
extern int yyparse __P((void));
extern int cfparse __P((void));
extern int cfreparse __P((void));
#endif /* _CFPARSE_PROTO_H */

View File

@ -0,0 +1,697 @@
/* $Id: cftoken.l,v 1.1.1.1 2005/02/12 11:11:45 manu Exp $ */
%{
/*
* Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 and 2003 WIDE Project.
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#include "config.h"
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <netinet/in.h>
#ifdef HAVE_NETINET6_IPSEC
# include <netinet6/ipsec.h>
#else
# include <netinet/ipsec.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#include <ctype.h>
#include <glob.h>
#ifdef HAVE_STDARG_H
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#include "var.h"
#include "misc.h"
#include "vmbuf.h"
#include "plog.h"
#include "debug.h"
#include "algorithm.h"
#include "cfparse_proto.h"
#include "cftoken_proto.h"
#include "localconf.h"
#include "oakley.h"
#include "isakmp_var.h"
#include "isakmp.h"
#include "ipsec_doi.h"
#include "proposal.h"
#include "nattraversal.h"
#ifdef GC
#include "gcmalloc.h"
#endif
#include "cfparse.h"
int yyerrorcount = 0;
#if defined(YIPS_DEBUG)
# define YYDB plog(LLV_DEBUG2, LOCATION, NULL, \
"begin <%d>%s\n", yy_start, yytext);
# define YYD { \
plog(LLV_DEBUG2, LOCATION, NULL, "<%d>%s", \
yy_start, loglevel >= LLV_DEBUG2 ? "\n" : ""); \
}
#else
# define YYDB
# define YYD
#endif /* defined(YIPS_DEBUG) */
#define MAX_INCLUDE_DEPTH 10
static struct include_stack {
char *path;
FILE *fp;
YY_BUFFER_STATE prevstate;
int lineno;
glob_t matches;
int matchon;
} incstack[MAX_INCLUDE_DEPTH];
static int incstackp = 0;
static int yy_first_time = 1;
%}
/* common seciton */
nl \n
ws [ \t]+
digit [0-9]
letter [A-Za-z]
hexdigit [0-9A-Fa-f]
/*octet (([01]?{digit}?{digit})|((2([0-4]{digit}))|(25[0-5]))) */
special [()+\|\?\*]
comma \,
dot \.
slash \/
bcl \{
ecl \}
blcl \[
elcl \]
percent \%
semi \;
comment \#.*
ccomment "/*"
bracketstring \<[^>]*\>
quotedstring \"[^"]*\"
addrstring [a-fA-F0-9:]([a-fA-F0-9:\.]*|[a-fA-F0-9:\.]*%[a-zA-Z0-9]*)
decstring {digit}+
hexstring 0x{hexdigit}+
%s S_INI S_PRIV S_PTH S_INF S_LOG S_PAD S_LST S_RTRY S_CFG
%s S_ALGST S_ALGCL
%s S_SAINF S_SAINFS
%s S_RMT S_RMTS S_RMTP
%s S_SA
%s S_GSSENC
%%
%{
if (yy_first_time) {
BEGIN S_INI;
yy_first_time = 0;
}
%}
/* privsep */
<S_INI>privsep { BEGIN S_PRIV; YYDB; return(PRIVSEP); }
<S_PRIV>{bcl} { return(BOC); }
<S_PRIV>user { YYD; return(USER); }
<S_PRIV>group { YYD; return(GROUP); }
<S_PRIV>{ecl} { BEGIN S_INI; return(EOC); }
/* path */
<S_INI>path { BEGIN S_PTH; YYDB; return(PATH); }
<S_PTH>include { YYD; yylval.num = LC_PATHTYPE_INCLUDE;
return(PATHTYPE); }
<S_PTH>pre_shared_key { YYD; yylval.num = LC_PATHTYPE_PSK;
return(PATHTYPE); }
<S_PTH>certificate { YYD; yylval.num = LC_PATHTYPE_CERT;
return(PATHTYPE); }
<S_PTH>backupsa { YYD; yylval.num = LC_PATHTYPE_BACKUPSA;
return(PATHTYPE); }
<S_PTH>{semi} { BEGIN S_INI; YYDB; return(EOS); }
/* include */
<S_INI>include { YYDB; return(INCLUDE); }
/* self information */
<S_INI>identifier { BEGIN S_INF; YYDB; yywarn("it is obsoleted. use \"my_identifier\" in each remote directives."); return(IDENTIFIER); }
<S_INF>{semi} { BEGIN S_INI; return(EOS); }
/* special */
<S_INI>complex_bundle { YYDB; return(COMPLEX_BUNDLE); }
/* logging */
<S_INI>log { BEGIN S_LOG; YYDB; return(LOGGING); }
<S_LOG>info { YYD; yywarn("it is obsoleted. use \"notify\""); yylval.num = 0; return(LOGLEV); }
<S_LOG>notify { YYD; yylval.num = 0; return(LOGLEV); }
<S_LOG>debug { YYD; yylval.num = 1; return(LOGLEV); }
<S_LOG>debug2 { YYD; yylval.num = 2; return(LOGLEV); }
<S_LOG>debug3 { YYD; yywarn("it is osboleted. use \"debug2\""); yylval.num = 2; return(LOGLEV); }
<S_LOG>debug4 { YYD; yywarn("it is obsoleted. use \"debug2\""); yylval.num = 2; return(LOGLEV); }
<S_LOG>{semi} { BEGIN S_INI; return(EOS); }
/* padding */
<S_INI>padding { BEGIN S_PAD; YYDB; return(PADDING); }
<S_PAD>{bcl} { return(BOC); }
<S_PAD>randomize { YYD; return(PAD_RANDOMIZE); }
<S_PAD>randomize_length { YYD; return(PAD_RANDOMIZELEN); }
<S_PAD>maximum_length { YYD; return(PAD_MAXLEN); }
<S_PAD>strict_check { YYD; return(PAD_STRICT); }
<S_PAD>exclusive_tail { YYD; return(PAD_EXCLTAIL); }
<S_PAD>{ecl} { BEGIN S_INI; return(EOC); }
/* listen */
<S_INI>listen { BEGIN S_LST; YYDB; return(LISTEN); }
<S_LST>{bcl} { return(BOC); }
<S_LST>isakmp { YYD; return(X_ISAKMP); }
<S_LST>isakmp_natt { YYD; return(X_ISAKMP_NATT); }
<S_LST>admin { YYD; return(X_ADMIN); }
<S_LST>adminsock { YYD; return(ADMINSOCK); }
<S_LST>disabled { YYD; return(DISABLED); }
<S_LST>strict_address { YYD; return(STRICT_ADDRESS); }
<S_LST>{ecl} { BEGIN S_INI; return(EOC); }
/* mode_cfg */
<S_INI>mode_cfg { BEGIN S_CFG; YYDB; return(MODECFG); }
<S_CFG>{bcl} { return(BOC); }
<S_CFG>network4 { YYD; return(CFG_NET4); }
<S_CFG>netmask4 { YYD; return(CFG_MASK4); }
<S_CFG>dns4 { YYD; return(CFG_DNS4); }
<S_CFG>wins4 { YYD; return(CFG_NBNS4); }
<S_CFG>auth_source { YYD; return(CFG_AUTH_SOURCE); }
<S_CFG>conf_source { YYD; return(CFG_CONF_SOURCE); }
<S_CFG>accounting { YYD; return(CFG_ACCOUNTING); }
<S_CFG>system { YYD; return(CFG_SYSTEM); }
<S_CFG>local { YYD; return(CFG_LOCAL); }
<S_CFG>none { YYD; return(CFG_NONE); }
<S_CFG>radius { YYD; return(CFG_RADIUS); }
<S_CFG>pam { YYD; return(CFG_PAM); }
<S_CFG>pool_size { YYD; return(CFG_POOL_SIZE); }
<S_CFG>banner { YYD; return(CFG_MOTD); }
<S_CFG>auth_throttle { YYD; return(CFG_AUTH_THROTTLE); }
<S_CFG>{ecl} { BEGIN S_INI; return(EOC); }
/* timer */
<S_INI>timer { BEGIN S_RTRY; YYDB; return(RETRY); }
<S_RTRY>{bcl} { return(BOC); }
<S_RTRY>counter { YYD; return(RETRY_COUNTER); }
<S_RTRY>interval { YYD; return(RETRY_INTERVAL); }
<S_RTRY>persend { YYD; return(RETRY_PERSEND); }
<S_RTRY>phase1 { YYD; return(RETRY_PHASE1); }
<S_RTRY>phase2 { YYD; return(RETRY_PHASE2); }
<S_RTRY>natt_keepalive { YYD; return(NATT_KA); }
<S_RTRY>{ecl} { BEGIN S_INI; return(EOC); }
/* sainfo */
<S_INI>sainfo { BEGIN S_SAINF; YYDB; return(SAINFO); }
<S_SAINF>anonymous { YYD; return(ANONYMOUS); }
<S_SAINF>{blcl}any{elcl} { YYD; return(PORTANY); }
<S_SAINF>any { YYD; return(ANY); }
<S_SAINF>from { YYD; return(FROM); }
/* sainfo spec */
<S_SAINF>{bcl} { BEGIN S_SAINFS; return(BOC); }
<S_SAINF>{semi} { BEGIN S_INI; return(EOS); }
<S_SAINFS>{ecl} { BEGIN S_INI; return(EOC); }
<S_SAINFS>pfs_group { YYD; return(PFS_GROUP); }
<S_SAINFS>identifier { YYD; yywarn("it is obsoleted. use \"my_identifier\"."); return(IDENTIFIER); }
<S_SAINFS>my_identifier { YYD; return(MY_IDENTIFIER); }
<S_SAINFS>lifetime { YYD; return(LIFETIME); }
<S_SAINFS>time { YYD; return(LIFETYPE_TIME); }
<S_SAINFS>byte { YYD; return(LIFETYPE_BYTE); }
<S_SAINFS>encryption_algorithm { YYD; yylval.num = algclass_ipsec_enc; return(ALGORITHM_CLASS); }
<S_SAINFS>authentication_algorithm { YYD; yylval.num = algclass_ipsec_auth; return(ALGORITHM_CLASS); }
<S_SAINFS>compression_algorithm { YYD; yylval.num = algclass_ipsec_comp; return(ALGORITHM_CLASS); }
<S_SAINFS>{comma} { YYD; return(COMMA); }
/* remote */
<S_INI>remote { BEGIN S_RMT; YYDB; return(REMOTE); }
<S_RMT>anonymous { YYD; return(ANONYMOUS); }
<S_RMT>inherit { YYD; return(INHERIT); }
/* remote spec */
<S_RMT>{bcl} { BEGIN S_RMTS; return(BOC); }
<S_RMTS>{ecl} { BEGIN S_INI; return(EOC); }
<S_RMTS>exchange_mode { YYD; return(EXCHANGE_MODE); }
<S_RMTS>{comma} { YYD; /* XXX ignored, but to be handled. */ ; }
<S_RMTS>base { YYD; yylval.num = ISAKMP_ETYPE_BASE; return(EXCHANGETYPE); }
<S_RMTS>main { YYD; yylval.num = ISAKMP_ETYPE_IDENT; return(EXCHANGETYPE); }
<S_RMTS>aggressive { YYD; yylval.num = ISAKMP_ETYPE_AGG; return(EXCHANGETYPE); }
<S_RMTS>doi { YYD; return(DOI); }
<S_RMTS>ipsec_doi { YYD; yylval.num = IPSEC_DOI; return(DOITYPE); }
<S_RMTS>situation { YYD; return(SITUATION); }
<S_RMTS>identity_only { YYD; yylval.num = IPSECDOI_SIT_IDENTITY_ONLY; return(SITUATIONTYPE); }
<S_RMTS>secrecy { YYD; yylval.num = IPSECDOI_SIT_SECRECY; return(SITUATIONTYPE); }
<S_RMTS>integrity { YYD; yylval.num = IPSECDOI_SIT_INTEGRITY; return(SITUATIONTYPE); }
<S_RMTS>identifier { YYD; yywarn("it is obsoleted. use \"my_identifier\"."); return(IDENTIFIER); }
<S_RMTS>my_identifier { YYD; return(MY_IDENTIFIER); }
<S_RMTS>xauth_login { YYD; return(XAUTH_LOGIN); /* formerly identifier type login */ }
<S_RMTS>peers_identifier { YYD; return(PEERS_IDENTIFIER); }
<S_RMTS>verify_identifier { YYD; return(VERIFY_IDENTIFIER); }
<S_RMTS>certificate_type { YYD; return(CERTIFICATE_TYPE); }
<S_RMTS>ca_type { YYD; return(CA_TYPE); }
<S_RMTS>x509 { YYD; yylval.num = ISAKMP_CERT_X509SIGN; return(CERT_X509); }
<S_RMTS>plain_rsa { YYD; yylval.num = ISAKMP_CERT_PLAINRSA; return(CERT_PLAINRSA); }
<S_RMTS>peers_certfile { YYD; return(PEERS_CERTFILE); }
<S_RMTS>dnssec { YYD; return(DNSSEC); }
<S_RMTS>verify_cert { YYD; return(VERIFY_CERT); }
<S_RMTS>send_cert { YYD; return(SEND_CERT); }
<S_RMTS>send_cr { YYD; return(SEND_CR); }
<S_RMTS>dh_group { YYD; return(DH_GROUP); }
<S_RMTS>nonce_size { YYD; return(NONCE_SIZE); }
<S_RMTS>generate_policy { YYD; return(GENERATE_POLICY); }
<S_RMTS>support_mip6 { YYD; yywarn("it is obsoleted. use \"support_proxy\"."); return(SUPPORT_PROXY); }
<S_RMTS>support_proxy { YYD; return(SUPPORT_PROXY); }
<S_RMTS>initial_contact { YYD; return(INITIAL_CONTACT); }
<S_RMTS>nat_traversal { YYD; return(NAT_TRAVERSAL); }
<S_RMTS>force { YYD; yylval.num = NATT_FORCE; return(NAT_TRAVERSAL_LEVEL); }
<S_RMTS>proposal_check { YYD; return(PROPOSAL_CHECK); }
<S_RMTS>obey { YYD; yylval.num = PROP_CHECK_OBEY; return(PROPOSAL_CHECK_LEVEL); }
<S_RMTS>strict { YYD; yylval.num = PROP_CHECK_STRICT; return(PROPOSAL_CHECK_LEVEL); }
<S_RMTS>exact { YYD; yylval.num = PROP_CHECK_EXACT; return(PROPOSAL_CHECK_LEVEL); }
<S_RMTS>claim { YYD; yylval.num = PROP_CHECK_CLAIM; return(PROPOSAL_CHECK_LEVEL); }
<S_RMTS>keepalive { YYD; return(KEEPALIVE); }
<S_RMTS>passive { YYD; return(PASSIVE); }
<S_RMTS>lifetime { YYD; return(LIFETIME); }
<S_RMTS>time { YYD; return(LIFETYPE_TIME); }
<S_RMTS>byte { YYD; return(LIFETYPE_BYTE); }
<S_RMTS>dpd { YYD; return(DPD); }
<S_RMTS>dpd_delay { YYD; return(DPD_DELAY); }
<S_RMTS>dpd_retry { YYD; return(DPD_RETRY); }
<S_RMTS>dpd_maxfail { YYD; return(DPD_MAXFAIL); }
<S_RMTS>ike_frag { YYD; return(IKE_FRAG); }
<S_RMTS>esp_frag { YYD; return(ESP_FRAG); }
<S_RMTS>script { YYD; return(SCRIPT); }
<S_RMTS>phase1_up { YYD; return(PHASE1_UP); }
<S_RMTS>phase1_down { YYD; return(PHASE1_DOWN); }
<S_RMTS>mode_cfg { YYD; return(MODE_CFG); }
/* remote proposal */
<S_RMTS>proposal { BEGIN S_RMTP; YYDB; return(PROPOSAL); }
<S_RMTP>{bcl} { return(BOC); }
<S_RMTP>{ecl} { BEGIN S_RMTS; return(EOC); }
<S_RMTP>lifetime { YYD; return(LIFETIME); }
<S_RMTP>time { YYD; return(LIFETYPE_TIME); }
<S_RMTP>byte { YYD; return(LIFETYPE_BYTE); }
<S_RMTP>encryption_algorithm { YYD; yylval.num = algclass_isakmp_enc; return(ALGORITHM_CLASS); }
<S_RMTP>authentication_method { YYD; yylval.num = algclass_isakmp_ameth; return(ALGORITHM_CLASS); }
<S_RMTP>hash_algorithm { YYD; yylval.num = algclass_isakmp_hash; return(ALGORITHM_CLASS); }
<S_RMTP>dh_group { YYD; return(DH_GROUP); }
<S_RMTP>gss_id { YYD; return(GSS_ID); }
<S_RMTP>gssapi_id { YYD; return(GSS_ID); } /* for back compatibility */
/* GSS ID encoding type (global) */
<S_INI>gss_id_enc { BEGIN S_GSSENC; YYDB; return(GSS_ID_ENC); }
<S_GSSENC>latin1 { YYD; yylval.num = LC_GSSENC_LATIN1;
return(GSS_ID_ENCTYPE); }
<S_GSSENC>utf-16le { YYD; yylval.num = LC_GSSENC_UTF16LE;
return(GSS_ID_ENCTYPE); }
<S_GSSENC>{semi} { BEGIN S_INI; YYDB; return(EOS); }
/* parameter */
on { YYD; yylval.num = TRUE; return(SWITCH); }
off { YYD; yylval.num = FALSE; return(SWITCH); }
/* prefix */
{slash}{digit}{1,3} {
YYD;
yytext++;
yylval.num = atoi(yytext);
return(PREFIX);
}
/* port number */
{blcl}{decstring}{elcl} {
char *p = yytext;
YYD;
while (*++p != ']') ;
*p = 0;
yytext++;
yylval.num = atoi(yytext);
return(PORT);
}
/* upper protocol */
esp { YYD; yylval.num = IPPROTO_ESP; return(UL_PROTO); }
ah { YYD; yylval.num = IPPROTO_AH; return(UL_PROTO); }
ipcomp { YYD; yylval.num = IPPROTO_IPCOMP; return(UL_PROTO); }
icmp { YYD; yylval.num = IPPROTO_ICMP; return(UL_PROTO); }
icmp6 { YYD; yylval.num = IPPROTO_ICMPV6; return(UL_PROTO); }
tcp { YYD; yylval.num = IPPROTO_TCP; return(UL_PROTO); }
udp { YYD; yylval.num = IPPROTO_UDP; return(UL_PROTO); }
/* algorithm type */
des_iv64 { YYD; yylval.num = algtype_des_iv64; return(ALGORITHMTYPE); }
des { YYD; yylval.num = algtype_des; return(ALGORITHMTYPE); }
3des { YYD; yylval.num = algtype_3des; return(ALGORITHMTYPE); }
rc5 { YYD; yylval.num = algtype_rc5; return(ALGORITHMTYPE); }
idea { YYD; yylval.num = algtype_idea; return(ALGORITHMTYPE); }
cast128 { YYD; yylval.num = algtype_cast128; return(ALGORITHMTYPE); }
blowfish { YYD; yylval.num = algtype_blowfish; return(ALGORITHMTYPE); }
3idea { YYD; yylval.num = algtype_3idea; return(ALGORITHMTYPE); }
des_iv32 { YYD; yylval.num = algtype_des_iv32; return(ALGORITHMTYPE); }
rc4 { YYD; yylval.num = algtype_rc4; return(ALGORITHMTYPE); }
null_enc { YYD; yylval.num = algtype_null_enc; return(ALGORITHMTYPE); }
null { YYD; yylval.num = algtype_null_enc; return(ALGORITHMTYPE); }
aes { YYD; yylval.num = algtype_aes; return(ALGORITHMTYPE); }
rijndael { YYD; yylval.num = algtype_aes; return(ALGORITHMTYPE); }
twofish { YYD; yylval.num = algtype_twofish; return(ALGORITHMTYPE); }
non_auth { YYD; yylval.num = algtype_non_auth; return(ALGORITHMTYPE); }
hmac_md5 { YYD; yylval.num = algtype_hmac_md5; return(ALGORITHMTYPE); }
hmac_sha1 { YYD; yylval.num = algtype_hmac_sha1; return(ALGORITHMTYPE); }
hmac_sha2_256 { YYD; yylval.num = algtype_hmac_sha2_256; return(ALGORITHMTYPE); }
hmac_sha2_384 { YYD; yylval.num = algtype_hmac_sha2_384; return(ALGORITHMTYPE); }
hmac_sha2_512 { YYD; yylval.num = algtype_hmac_sha2_512; return(ALGORITHMTYPE); }
des_mac { YYD; yylval.num = algtype_des_mac; return(ALGORITHMTYPE); }
kpdk { YYD; yylval.num = algtype_kpdk; return(ALGORITHMTYPE); }
md5 { YYD; yylval.num = algtype_md5; return(ALGORITHMTYPE); }
sha1 { YYD; yylval.num = algtype_sha1; return(ALGORITHMTYPE); }
tiger { YYD; yylval.num = algtype_tiger; return(ALGORITHMTYPE); }
sha2_256 { YYD; yylval.num = algtype_sha2_256; return(ALGORITHMTYPE); }
sha2_384 { YYD; yylval.num = algtype_sha2_384; return(ALGORITHMTYPE); }
sha2_512 { YYD; yylval.num = algtype_sha2_512; return(ALGORITHMTYPE); }
oui { YYD; yylval.num = algtype_oui; return(ALGORITHMTYPE); }
deflate { YYD; yylval.num = algtype_deflate; return(ALGORITHMTYPE); }
lzs { YYD; yylval.num = algtype_lzs; return(ALGORITHMTYPE); }
modp768 { YYD; yylval.num = algtype_modp768; return(ALGORITHMTYPE); }
modp1024 { YYD; yylval.num = algtype_modp1024; return(ALGORITHMTYPE); }
modp1536 { YYD; yylval.num = algtype_modp1536; return(ALGORITHMTYPE); }
ec2n155 { YYD; yylval.num = algtype_ec2n155; return(ALGORITHMTYPE); }
ec2n185 { YYD; yylval.num = algtype_ec2n185; return(ALGORITHMTYPE); }
modp2048 { YYD; yylval.num = algtype_modp2048; return(ALGORITHMTYPE); }
modp3072 { YYD; yylval.num = algtype_modp3072; return(ALGORITHMTYPE); }
modp4096 { YYD; yylval.num = algtype_modp4096; return(ALGORITHMTYPE); }
modp6144 { YYD; yylval.num = algtype_modp6144; return(ALGORITHMTYPE); }
modp8192 { YYD; yylval.num = algtype_modp8192; return(ALGORITHMTYPE); }
pre_shared_key { YYD; yylval.num = algtype_psk; return(ALGORITHMTYPE); }
rsasig { YYD; yylval.num = algtype_rsasig; return(ALGORITHMTYPE); }
dsssig { YYD; yylval.num = algtype_dsssig; return(ALGORITHMTYPE); }
rsaenc { YYD; yylval.num = algtype_rsaenc; return(ALGORITHMTYPE); }
rsarev { YYD; yylval.num = algtype_rsarev; return(ALGORITHMTYPE); }
gssapi_krb { YYD; yylval.num = algtype_gssapikrb; return(ALGORITHMTYPE); }
hybrid_rsa_server {
#ifdef ENABLE_HYBRID
YYD; yylval.num = algtype_hybrid_rsa_s; return(ALGORITHMTYPE);
#else
yyerror("racoon not configured with --enable-hybrid");
#endif
}
hybrid_dss_server {
#ifdef ENABLE_HYBRID
YYD; yylval.num = algtype_hybrid_dss_s; return(ALGORITHMTYPE);
#else
yyerror("racoon not configured with --enable-hybrid");
#endif
}
hybrid_rsa_client {
#ifdef ENABLE_HYBRID
YYD; yylval.num = algtype_hybrid_rsa_c; return(ALGORITHMTYPE);
#else
yyerror("racoon not configured with --enable-hybrid");
#endif
}
hybrid_dss_client {
#ifdef ENABLE_HYBRID
YYD; yylval.num = algtype_hybrid_dss_c; return(ALGORITHMTYPE);
#else
yyerror("racoon not configured with --enable-hybrid");
#endif
}
/* identifier type */
vendor_id { YYD; yywarn("it is obsoleted."); return(VENDORID); }
user_fqdn { YYD; yylval.num = IDTYPE_USERFQDN; return(IDENTIFIERTYPE); }
fqdn { YYD; yylval.num = IDTYPE_FQDN; return(IDENTIFIERTYPE); }
keyid { YYD; yylval.num = IDTYPE_KEYID; return(IDENTIFIERTYPE); }
address { YYD; yylval.num = IDTYPE_ADDRESS; return(IDENTIFIERTYPE); }
asn1dn { YYD; yylval.num = IDTYPE_ASN1DN; return(IDENTIFIERTYPE); }
certname { YYD; yywarn("certname will be obsoleted in near future."); yylval.num = IDTYPE_ASN1DN; return(IDENTIFIERTYPE); }
/* units */
B|byte|bytes { YYD; return(UNITTYPE_BYTE); }
KB { YYD; return(UNITTYPE_KBYTES); }
MB { YYD; return(UNITTYPE_MBYTES); }
TB { YYD; return(UNITTYPE_TBYTES); }
sec|secs|second|seconds { YYD; return(UNITTYPE_SEC); }
min|mins|minute|minutes { YYD; return(UNITTYPE_MIN); }
hour|hours { YYD; return(UNITTYPE_HOUR); }
/* boolean */
yes { YYD; yylval.num = TRUE; return(BOOLEAN); }
no { YYD; yylval.num = FALSE; return(BOOLEAN); }
{decstring} {
char *bp;
YYD;
yylval.num = strtol(yytext, &bp, 10);
return(NUMBER);
}
{hexstring} {
char *p;
YYD;
yylval.val = vmalloc(yyleng + (yyleng & 1) + 1);
if (yylval.val == NULL) {
yyerror("vmalloc failed");
return -1;
}
p = yylval.val->v;
*p++ = '0';
*p++ = 'x';
/* fixed string if length is odd. */
if (yyleng & 1)
*p++ = '0';
memcpy(p, &yytext[2], yyleng - 1);
return(HEXSTRING);
}
{quotedstring} {
u_char *p = yytext;
YYD;
while (*++p != '"') ;
*p = '\0';
yylval.val = vmalloc(yyleng - 1);
if (yylval.val == NULL) {
yyerror("vmalloc failed");
return -1;
}
memcpy(yylval.val->v, &yytext[1], yylval.val->l);
return(QUOTEDSTRING);
}
{addrstring} {
YYD;
yylval.val = vmalloc(yyleng + 1);
if (yylval.val == NULL) {
yyerror("vmalloc failed");
return -1;
}
memcpy(yylval.val->v, yytext, yylval.val->l);
return(ADDRSTRING);
}
<<EOF>> {
yy_delete_buffer(YY_CURRENT_BUFFER);
incstackp--;
nextfile:
if (incstack[incstackp].matchon <
incstack[incstackp].matches.gl_pathc) {
char* filepath = incstack[incstackp].matches.gl_pathv[incstack[incstackp].matchon];
incstack[incstackp].matchon++;
incstackp++;
if (yycf_set_buffer(filepath) != 0) {
incstackp--;
goto nextfile;
}
yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
BEGIN(S_INI);
} else {
globfree(&incstack[incstackp].matches);
if (incstackp == 0)
yyterminate();
else
yy_switch_to_buffer(incstack[incstackp].prevstate);
}
}
/* ... */
{ws} { ; }
{nl} { incstack[incstackp].lineno++; }
{comment} { YYD; }
{semi} { return(EOS); }
. { yymore(); }
%%
void
yyerror(char *s, ...)
{
char fmt[512];
va_list ap;
#ifdef HAVE_STDARG_H
va_start(ap, s);
#else
va_start(ap);
#endif
snprintf(fmt, sizeof(fmt), "%s:%d: \"%s\" %s\n",
incstack[incstackp].path, incstack[incstackp].lineno,
yytext, s);
plogv(LLV_ERROR, LOCATION, NULL, fmt, ap);
va_end(ap);
yyerrorcount++;
}
void
yywarn(char *s, ...)
{
char fmt[512];
va_list ap;
#ifdef HAVE_STDARG_H
va_start(ap, s);
#else
va_start(ap);
#endif
snprintf(fmt, sizeof(fmt), "%s:%d: \"%s\" %s\n",
incstack[incstackp].path, incstack[incstackp].lineno,
yytext, s);
plogv(LLV_WARNING, LOCATION, NULL, fmt, ap);
va_end(ap);
}
int
yycf_switch_buffer(path)
char *path;
{
char *filepath = NULL;
/* got the include file name */
if (incstackp >= MAX_INCLUDE_DEPTH) {
plog(LLV_ERROR, LOCATION, NULL,
"Includes nested too deeply");
return -1;
}
if (glob(path, GLOB_TILDE, NULL, &incstack[incstackp].matches) != 0 ||
incstack[incstackp].matches.gl_pathc == 0) {
plog(LLV_ERROR, LOCATION, NULL,
"glob found no matches for path");
return -1;
}
incstack[incstackp].matchon = 0;
incstack[incstackp].prevstate = YY_CURRENT_BUFFER;
nextmatch:
if (incstack[incstackp].matchon >= incstack[incstackp].matches.gl_pathc)
return -1;
filepath =
incstack[incstackp].matches.gl_pathv[incstack[incstackp].matchon];
incstack[incstackp].matchon++;
incstackp++;
if (yycf_set_buffer(filepath) != 0) {
incstackp--;
goto nextmatch;
}
yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
BEGIN(S_INI);
return 0;
}
int
yycf_set_buffer(path)
char *path;
{
yyin = fopen(path, "r");
if (yyin == NULL) {
fprintf(stderr, "failed to open file %s (%s)\n",
path, strerror(errno));
plog(LLV_ERROR, LOCATION, NULL,
"failed to open file %s (%s)\n",
path, strerror(errno));
return -1;
}
/* initialize */
incstack[incstackp].fp = yyin;
incstack[incstackp].path = strdup(path);
incstack[incstackp].lineno = 1;
plog(LLV_DEBUG, LOCATION, NULL,
"reading config file %s\n", path);
return 0;
}
void
yycf_init_buffer()
{
int i;
for (i = 0; i < MAX_INCLUDE_DEPTH; i++)
memset(&incstack[i], 0, sizeof(incstack[i]));
incstackp = 0;
}
void
yycf_clean_buffer()
{
int i;
for (i = 0; i < MAX_INCLUDE_DEPTH; i++) {
if (incstack[i].path != NULL) {
fclose(incstack[i].fp);
racoon_free(incstack[i].path);
incstack[i].path = NULL;
}
}
}

View File

@ -0,0 +1,46 @@
/* $Id: cftoken_proto.h,v 1.1.1.1 2005/02/12 11:11:43 manu Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#ifndef _CFTOKEN_PROTO_H
#define _CFTOKEN_PROTO_H
extern int yyerrorcount;
extern int yylex __P((void));
extern void yyerror __P((char *, ...));
extern void yywarn __P((char *, ...));
extern int yycf_switch_buffer __P((char *));
extern int yycf_set_buffer __P((char *));
extern void yycf_init_buffer __P((void));
extern void yycf_clean_buffer __P((void));
#endif /* _CFTOKEN_PROTO_H */

View File

@ -0,0 +1,21 @@
#! /usr/pkg/bin/perl
die "insufficient arguments" if (scalar(@ARGV) < 2);
$src = $ARGV[0];
$dst = $ARGV[1];
$mode = 'transport';
if (scalar(@ARGV) > 2) {
$mode = $ARGV[2];
}
open(OUT, "|setkey -c");
if ($mode eq 'transport') {
print STDERR "install esp transport mode: $src -> $dst\n";
print OUT "spdadd $src $dst any -P out ipsec esp/transport//require;\n";
print OUT "spdadd $dst $src any -P in ipsec esp/transport//require;\n";
} elsif ($mode eq 'delete') {
print STDERR "delete policy: $src -> $dst\n";
print OUT "spddelete $src $dst any -P out;\n";
print OUT "spddelete $dst $src any -P in;\n";
}
close(OUT);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,224 @@
/* $Id: crypto_openssl.h,v 1.1.1.1 2005/02/12 11:11:50 manu Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#ifndef _CRYPTO_OPENSSL_H
#define _CRYPTO_OPENSSL_H
#include "crypto_openssl.h"
#include <openssl/x509v3.h>
#include <openssl/rsa.h>
#define GENT_OTHERNAME GEN_OTHERNAME
#define GENT_EMAIL GEN_EMAIL
#define GENT_DNS GEN_DNS
#define GENT_X400 GEN_X400
#define GENT_DIRNAME GEN_DIRNAME
#define GENT_EDIPARTY GEN_EDIPARTY
#define GENT_URI GEN_URI
#define GENT_IPADD GEN_IPADD
#define GENT_RID GEN_RID
extern vchar_t *eay_str2asn1dn __P((const char *, int));
extern vchar_t *eay_hex2asn1dn __P((const char *, int));
extern int eay_cmp_asn1dn __P((vchar_t *, vchar_t *));
extern int eay_check_x509cert __P((vchar_t *, char *, char *, int));
extern vchar_t *eay_get_x509asn1subjectname __P((vchar_t *));
extern int eay_get_x509subjectaltname __P((vchar_t *, char **, int *, int));
extern char *eay_get_x509text __P((vchar_t *));
extern vchar_t *eay_get_x509cert __P((char *));
extern vchar_t *eay_get_x509sign __P((vchar_t *, vchar_t *));
extern int eay_check_x509sign __P((vchar_t *, vchar_t *, vchar_t *));
extern int eay_check_rsasign __P((vchar_t *, vchar_t *, RSA *));
extern vchar_t *eay_get_rsasign __P((vchar_t *, RSA *));
/* RSA */
extern vchar_t *eay_rsa_sign __P((vchar_t *, RSA *));
extern int eay_rsa_verify __P((vchar_t *, vchar_t *, RSA *));
/* ASN.1 */
extern vchar_t *eay_get_pkcs1privkey __P((char *));
extern vchar_t *eay_get_pkcs1pubkey __P((char *));
/* string error */
extern char *eay_strerror __P((void));
/* OpenSSL initialization */
extern void eay_init __P((void));
/* Generic EVP */
extern vchar_t *evp_crypt __P((vchar_t *data, vchar_t *key, vchar_t *iv,
const EVP_CIPHER *e, int enc));
extern int evp_weakkey __P((vchar_t *key, const EVP_CIPHER *e));
extern int evp_keylen __P((int len, const EVP_CIPHER *e));
/* DES */
extern vchar_t *eay_des_encrypt __P((vchar_t *, vchar_t *, vchar_t *));
extern vchar_t *eay_des_decrypt __P((vchar_t *, vchar_t *, vchar_t *));
extern int eay_des_weakkey __P((vchar_t *));
extern int eay_des_keylen __P((int));
/* IDEA */
extern vchar_t *eay_idea_encrypt __P((vchar_t *, vchar_t *, vchar_t *));
extern vchar_t *eay_idea_decrypt __P((vchar_t *, vchar_t *, vchar_t *));
extern int eay_idea_weakkey __P((vchar_t *));
extern int eay_idea_keylen __P((int));
/* blowfish */
extern vchar_t *eay_bf_encrypt __P((vchar_t *, vchar_t *, vchar_t *));
extern vchar_t *eay_bf_decrypt __P((vchar_t *, vchar_t *, vchar_t *));
extern int eay_bf_weakkey __P((vchar_t *));
extern int eay_bf_keylen __P((int));
/* RC5 */
extern vchar_t *eay_rc5_encrypt __P((vchar_t *, vchar_t *, vchar_t *));
extern vchar_t *eay_rc5_decrypt __P((vchar_t *, vchar_t *, vchar_t *));
extern int eay_rc5_weakkey __P((vchar_t *));
extern int eay_rc5_keylen __P((int));
/* 3DES */
extern vchar_t *eay_3des_encrypt __P((vchar_t *, vchar_t *, vchar_t *));
extern vchar_t *eay_3des_decrypt __P((vchar_t *, vchar_t *, vchar_t *));
extern int eay_3des_weakkey __P((vchar_t *));
extern int eay_3des_keylen __P((int));
/* CAST */
extern vchar_t *eay_cast_encrypt __P((vchar_t *, vchar_t *, vchar_t *));
extern vchar_t *eay_cast_decrypt __P((vchar_t *, vchar_t *, vchar_t *));
extern int eay_cast_weakkey __P((vchar_t *));
extern int eay_cast_keylen __P((int));
/* AES(RIJNDAEL) */
extern vchar_t *eay_aes_encrypt __P((vchar_t *, vchar_t *, vchar_t *));
extern vchar_t *eay_aes_decrypt __P((vchar_t *, vchar_t *, vchar_t *));
extern int eay_aes_weakkey __P((vchar_t *));
extern int eay_aes_keylen __P((int));
/* misc */
extern int eay_null_keylen __P((int));
extern int eay_null_hashlen __P((void));
extern int eay_kpdk_hashlen __P((void));
extern int eay_twofish_keylen __P((int));
/* hash */
#if defined(WITH_SHA2)
/* HMAC SHA2 */
extern vchar_t *eay_hmacsha2_512_one __P((vchar_t *, vchar_t *));
extern caddr_t eay_hmacsha2_512_init __P((vchar_t *));
extern void eay_hmacsha2_512_update __P((caddr_t, vchar_t *));
extern vchar_t *eay_hmacsha2_512_final __P((caddr_t));
extern vchar_t *eay_hmacsha2_384_one __P((vchar_t *, vchar_t *));
extern caddr_t eay_hmacsha2_384_init __P((vchar_t *));
extern void eay_hmacsha2_384_update __P((caddr_t, vchar_t *));
extern vchar_t *eay_hmacsha2_384_final __P((caddr_t));
extern vchar_t *eay_hmacsha2_256_one __P((vchar_t *, vchar_t *));
extern caddr_t eay_hmacsha2_256_init __P((vchar_t *));
extern void eay_hmacsha2_256_update __P((caddr_t, vchar_t *));
extern vchar_t *eay_hmacsha2_256_final __P((caddr_t));
#endif
/* HMAC SHA1 */
extern vchar_t *eay_hmacsha1_one __P((vchar_t *, vchar_t *));
extern caddr_t eay_hmacsha1_init __P((vchar_t *));
extern void eay_hmacsha1_update __P((caddr_t, vchar_t *));
extern vchar_t *eay_hmacsha1_final __P((caddr_t));
/* HMAC MD5 */
extern vchar_t *eay_hmacmd5_one __P((vchar_t *, vchar_t *));
extern caddr_t eay_hmacmd5_init __P((vchar_t *));
extern void eay_hmacmd5_update __P((caddr_t, vchar_t *));
extern vchar_t *eay_hmacmd5_final __P((caddr_t));
#if defined(WITH_SHA2)
/* SHA2 functions */
extern caddr_t eay_sha2_512_init __P((void));
extern void eay_sha2_512_update __P((caddr_t, vchar_t *));
extern vchar_t *eay_sha2_512_final __P((caddr_t));
extern vchar_t *eay_sha2_512_one __P((vchar_t *));
#endif
extern int eay_sha2_512_hashlen __P((void));
#if defined(WITH_SHA2)
extern caddr_t eay_sha2_384_init __P((void));
extern void eay_sha2_384_update __P((caddr_t, vchar_t *));
extern vchar_t *eay_sha2_384_final __P((caddr_t));
extern vchar_t *eay_sha2_384_one __P((vchar_t *));
#endif
extern int eay_sha2_384_hashlen __P((void));
#if defined(WITH_SHA2)
extern caddr_t eay_sha2_256_init __P((void));
extern void eay_sha2_256_update __P((caddr_t, vchar_t *));
extern vchar_t *eay_sha2_256_final __P((caddr_t));
extern vchar_t *eay_sha2_256_one __P((vchar_t *));
#endif
extern int eay_sha2_256_hashlen __P((void));
/* SHA functions */
extern caddr_t eay_sha1_init __P((void));
extern void eay_sha1_update __P((caddr_t, vchar_t *));
extern vchar_t *eay_sha1_final __P((caddr_t));
extern vchar_t *eay_sha1_one __P((vchar_t *));
extern int eay_sha1_hashlen __P((void));
/* MD5 functions */
extern caddr_t eay_md5_init __P((void));
extern void eay_md5_update __P((caddr_t, vchar_t *));
extern vchar_t *eay_md5_final __P((caddr_t));
extern vchar_t *eay_md5_one __P((vchar_t *));
extern int eay_md5_hashlen __P((void));
/* RNG */
extern vchar_t *eay_set_random __P((u_int32_t));
extern u_int32_t eay_random __P((void));
/* DH */
extern int eay_dh_generate __P((vchar_t *, u_int32_t, u_int, vchar_t **, vchar_t **));
extern int eay_dh_compute __P((vchar_t *, u_int32_t, vchar_t *, vchar_t *, vchar_t *, vchar_t **));
/* Base 64 */
vchar_t *base64_encode(char *in, long inlen);
vchar_t *base64_decode(char *in, long inlen);
RSA *base64_pubkey2rsa(char *in);
RSA *bignum_pubkey2rsa(BIGNUM *in);
/* misc */
extern int eay_revbnl __P((vchar_t *));
#include <openssl/bn.h>
extern int eay_v2bn __P((BIGNUM **, vchar_t *));
extern int eay_bn2v __P((vchar_t **, BIGNUM *));
extern const char *eay_version __P((void));
#define CBC_BLOCKLEN 8
#define IPSEC_ENCRYPTKEYLEN 8
#endif /* _CRYPTO_OPENSSL_H */

View File

@ -0,0 +1,39 @@
/* $Id: debug.h,v 1.1.1.1 2005/02/12 11:11:50 manu Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#ifndef _DEBUG_H
#define _DEBUG_H
/* define by main.c */
extern int f_local;
extern int vflag;
#endif /* _DEBUG_H */

View File

@ -0,0 +1,276 @@
/* $KAME: debugrm.c,v 1.6 2001/12/13 16:07:46 sakane Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#define NONEED_DRM
#include "config.h"
#include <sys/types.h>
#include <sys/param.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <err.h>
#include "debugrm.h"
#include "vmbuf.h" /* need to mask vmbuf.c functions. */
#define DRMLISTSIZE 1024
struct drm_list_t {
void *ptr;
char msg[100];
};
static struct drm_list_t drmlist[DRMLISTSIZE];
static int drm_unknown;
static void DRM_add __P((void *, char *));
static void DRM_del __P((void *));
static void DRM_setmsg __P((char *, int, void *, int, char *, int, char *));
void
DRM_init()
{
int i;
drm_unknown = 0;
for (i = 0; i < sizeof(drmlist)/sizeof(drmlist[0]); i++)
drmlist[i].ptr = 0;
}
void
DRM_dump()
{
FILE *fp;
int i;
fp = fopen(DRMDUMPFILE, "w");
if (fp == NULL)
err(1, "fopen"); /*XXX*/
fprintf(fp, "drm_unknown=%d\n", drm_unknown);
for (i = 0; i < sizeof(drmlist)/sizeof(drmlist[0]); i++) {
if (drmlist[i].ptr)
fprintf(fp, "%s\n", drmlist[i].msg);
}
fclose(fp);
}
static void
DRM_add(p, msg)
void *p;
char *msg;
{
int i;
for (i = 0; i < sizeof(drmlist)/sizeof(drmlist[0]); i++) {
if (!drmlist[i].ptr) {
drmlist[i].ptr = p;
strlcpy(drmlist[i].msg, msg, sizeof(drmlist[i].msg));
return;
}
}
}
static void
DRM_del(p)
void *p;
{
int i;
if (!p)
return;
for (i = 0; i < sizeof(drmlist)/sizeof(drmlist[0]); i++) {
if (drmlist[i].ptr == p) {
drmlist[i].ptr = 0;
return;
}
}
drm_unknown++;
}
static void
DRM_setmsg(buf, buflen, ptr, size, file, line, func)
char *buf, *file, *func;
int buflen, size, line;
void *ptr;
{
time_t t;
struct tm *tm;
int len;
t = time(NULL);
tm = localtime(&t);
len = strftime(buf, buflen, "%Y/%m/%d:%T ", tm);
snprintf(buf + len, buflen - len, "%p %6d %s:%d:%s",
ptr, size, file , line, func);
}
void *
DRM_malloc(file, line, func, size)
char *file, *func;
int line;
size_t size;
{
void *p;
p = malloc(size);
if (p) {
char buf[1024];
DRM_setmsg(buf, sizeof(buf), p, size, file, line, func);
DRM_add(p, buf);
}
return p;
}
void *
DRM_calloc(file, line, func, number, size)
char *file, *func;
int line;
size_t number, size;
{
void *p;
p = calloc(number, size);
if (p) {
char buf[1024];
DRM_setmsg(buf, sizeof(buf), p, number * size, file, line, func);
DRM_add(p, buf);
}
return p;
}
void *
DRM_realloc(file, line, func, ptr, size)
char *file, *func;
int line;
void *ptr;
size_t size;
{
void *p;
p = realloc(ptr, size);
if (p) {
char buf[1024];
if (ptr && p != ptr) {
DRM_del(ptr);
DRM_setmsg(buf, sizeof(buf), p, size, file, line, func);
DRM_add(p, buf);
}
}
return p;
}
void
DRM_free(file, line, func, ptr)
char *file, *func;
int line;
void *ptr;
{
DRM_del(ptr);
free(ptr);
}
/*
* mask vmbuf.c functions.
*/
void *
DRM_vmalloc(file, line, func, size)
char *file, *func;
int line;
size_t size;
{
void *p;
p = vmalloc(size);
if (p) {
char buf[1024];
DRM_setmsg(buf, sizeof(buf), p, size, file, line, func);
DRM_add(p, buf);
}
return p;
}
void *
DRM_vrealloc(file, line, func, ptr, size)
char *file, *func;
int line;
void *ptr;
size_t size;
{
void *p;
p = vrealloc(ptr, size);
if (p) {
char buf[1024];
if (ptr && p != ptr) {
DRM_del(ptr);
DRM_setmsg(buf, sizeof(buf), p, size, file, line, func);
DRM_add(p, buf);
}
}
return p;
}
void
DRM_vfree(file, line, func, ptr)
char *file, *func;
int line;
void *ptr;
{
DRM_del(ptr);
vfree(ptr);
}
void *
DRM_vdup(file, line, func, ptr)
char *file, *func;
int line;
void *ptr;
{
void *p;
p = vdup(ptr);
if (p) {
char buf[1024];
DRM_setmsg(buf, sizeof(buf), p, 0, file, line, func);
DRM_add(p, buf);
}
return p;
}

View File

@ -0,0 +1,92 @@
/* $Id: debugrm.h,v 1.1.1.1 2005/02/12 11:11:50 manu Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#ifndef _DEBUGRM_H
#define _DEBUGRM_H
#define DRMDUMPFILE "/var/tmp/debugrm.dump"
#ifdef NONEED_DRM
#ifndef racoon_malloc
#define racoon_malloc(sz) malloc((sz))
#endif
#ifndef racoon_calloc
#define racoon_calloc(cnt, sz) calloc((cnt), (sz))
#endif
#ifndef racoon_realloc
#define racoon_realloc(old, sz) realloc((old), (sz))
#endif
#ifndef racoon_free
#define racoon_free(p) free((p))
#endif
#else /*!NONEED_DRM*/
#ifndef racoon_malloc
#define racoon_malloc(sz) \
DRM_malloc(__FILE__, __LINE__, __func__, (sz))
#endif
#ifndef racoon_calloc
#define racoon_calloc(cnt, sz) \
DRM_calloc(__FILE__, __LINE__, __func__, (cnt), (sz))
#endif
#ifndef racoon_realloc
#define racoon_realloc(old, sz) \
DRM_realloc(__FILE__, __LINE__, __func__, (old), (sz))
#endif
#ifndef racoon_free
#define racoon_free(p) \
DRM_free(__FILE__, __LINE__, __func__, (p))
#endif
#endif /*NONEED_DRM*/
extern void DRM_init __P((void));
extern void DRM_dump __P((void));
extern void *DRM_malloc __P((char *, int, char *, size_t));
extern void *DRM_calloc __P((char *, int, char *, size_t, size_t));
extern void *DRM_realloc __P((char *, int, char *, void *, size_t));
extern void DRM_free __P((char *, int, char *, void *));
#ifndef NONEED_DRM
#define vmalloc(sz) \
DRM_vmalloc(__FILE__, __LINE__, __func__, (sz))
#define vdup(old) \
DRM_vdup(__FILE__, __LINE__, __func__, (old))
#define vrealloc(old, sz) \
DRM_vrealloc(__FILE__, __LINE__, __func__, (old), (sz))
#define vfree(p) \
DRM_vfree(__FILE__, __LINE__, __func__, (p))
#endif
extern void *DRM_vmalloc __P((char *, int, char *, size_t));
extern void *DRM_vrealloc __P((char *, int, char *, void *, size_t));
extern void DRM_vfree __P((char *, int, char *, void *));
extern void *DRM_vdup __P((char *, int, char *, void *));
#endif /* _DEBUGRM_H */

View File

@ -0,0 +1,203 @@
/* $Id: dhgroup.h,v 1.1.1.1 2005/02/12 11:11:51 manu Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#ifndef _DHGROUP_H
#define _DHGROUP_H
#define OAKLEY_PRIME_MODP768 \
"FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" \
"29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" \
"EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" \
"E485B576 625E7EC6 F44C42E9 A63A3620 FFFFFFFF FFFFFFFF"
#define OAKLEY_PRIME_MODP1024 \
"FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" \
"29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" \
"EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" \
"E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" \
"EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381" \
"FFFFFFFF FFFFFFFF"
#define OAKLEY_PRIME_MODP1536 \
"FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" \
"29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" \
"EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" \
"E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" \
"EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" \
"C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" \
"83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" \
"670C354E 4ABC9804 F1746C08 CA237327 FFFFFFFF FFFFFFFF"
/* RFC 3526 */
#define OAKLEY_PRIME_MODP2048 \
"FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" \
"29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" \
"EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" \
"E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" \
"EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" \
"C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" \
"83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" \
"670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" \
"E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" \
"DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" \
"15728E5A 8AACAA68 FFFFFFFF FFFFFFFF"
#define OAKLEY_PRIME_MODP3072 \
"FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" \
"29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" \
"EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" \
"E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" \
"EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" \
"C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" \
"83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" \
"670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" \
"E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" \
"DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" \
"15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64" \
"ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7" \
"ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B" \
"F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C" \
"BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31" \
"43DB5BFC E0FD108E 4B82D120 A93AD2CA FFFFFFFF FFFFFFFF"
#define OAKLEY_PRIME_MODP4096 \
"FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" \
"29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" \
"EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" \
"E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" \
"EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" \
"C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" \
"83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" \
"670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" \
"E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" \
"DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" \
"15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64" \
"ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7" \
"ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B" \
"F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C" \
"BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31" \
"43DB5BFC E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7" \
"88719A10 BDBA5B26 99C32718 6AF4E23C 1A946834 B6150BDA" \
"2583E9CA 2AD44CE8 DBBBC2DB 04DE8EF9 2E8EFC14 1FBECAA6" \
"287C5947 4E6BC05D 99B2964F A090C3A2 233BA186 515BE7ED" \
"1F612970 CEE2D7AF B81BDD76 2170481C D0069127 D5B05AA9" \
"93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34063199" \
"FFFFFFFF FFFFFFFF"
#define OAKLEY_PRIME_MODP6144 \
"FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" \
"29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" \
"EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" \
"E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" \
"EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" \
"C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" \
"83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" \
"670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" \
"E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" \
"DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" \
"15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64" \
"ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7" \
"ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B" \
"F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C" \
"BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31" \
"43DB5BFC E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7" \
"88719A10 BDBA5B26 99C32718 6AF4E23C 1A946834 B6150BDA" \
"2583E9CA 2AD44CE8 DBBBC2DB 04DE8EF9 2E8EFC14 1FBECAA6" \
"287C5947 4E6BC05D 99B2964F A090C3A2 233BA186 515BE7ED" \
"1F612970 CEE2D7AF B81BDD76 2170481C D0069127 D5B05AA9" \
"93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34028492" \
"36C3FAB4 D27C7026 C1D4DCB2 602646DE C9751E76 3DBA37BD" \
"F8FF9406 AD9E530E E5DB382F 413001AE B06A53ED 9027D831" \
"179727B0 865A8918 DA3EDBEB CF9B14ED 44CE6CBA CED4BB1B" \
"DB7F1447 E6CC254B 33205151 2BD7AF42 6FB8F401 378CD2BF" \
"5983CA01 C64B92EC F032EA15 D1721D03 F482D7CE 6E74FEF6" \
"D55E702F 46980C82 B5A84031 900B1C9E 59E7C97F BEC7E8F3" \
"23A97A7E 36CC88BE 0F1D45B7 FF585AC5 4BD407B2 2B4154AA" \
"CC8F6D7E BF48E1D8 14CC5ED2 0F8037E0 A79715EE F29BE328" \
"06A1D58B B7C5DA76 F550AA3D 8A1FBFF0 EB19CCB1 A313D55C" \
"DA56C9EC 2EF29632 387FE8D7 6E3C0468 043E8F66 3F4860EE" \
"12BF2D5B 0B7474D6 E694F91E 6DCC4024 FFFFFFFF FFFFFFFF"
#define OAKLEY_PRIME_MODP8192 \
"FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1" \
"29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD" \
"EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245" \
"E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED" \
"EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE45B3D" \
"C2007CB8 A163BF05 98DA4836 1C55D39A 69163FA8 FD24CF5F" \
"83655D23 DCA3AD96 1C62F356 208552BB 9ED52907 7096966D" \
"670C354E 4ABC9804 F1746C08 CA18217C 32905E46 2E36CE3B" \
"E39E772C 180E8603 9B2783A2 EC07A28F B5C55DF0 6F4C52C9" \
"DE2BCBF6 95581718 3995497C EA956AE5 15D22618 98FA0510" \
"15728E5A 8AAAC42D AD33170D 04507A33 A85521AB DF1CBA64" \
"ECFB8504 58DBEF0A 8AEA7157 5D060C7D B3970F85 A6E1E4C7" \
"ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226 1AD2EE6B" \
"F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C" \
"BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31" \
"43DB5BFC E0FD108E 4B82D120 A9210801 1A723C12 A787E6D7" \
"88719A10 BDBA5B26 99C32718 6AF4E23C 1A946834 B6150BDA" \
"2583E9CA 2AD44CE8 DBBBC2DB 04DE8EF9 2E8EFC14 1FBECAA6" \
"287C5947 4E6BC05D 99B2964F A090C3A2 233BA186 515BE7ED" \
"1F612970 CEE2D7AF B81BDD76 2170481C D0069127 D5B05AA9" \
"93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34028492" \
"36C3FAB4 D27C7026 C1D4DCB2 602646DE C9751E76 3DBA37BD" \
"F8FF9406 AD9E530E E5DB382F 413001AE B06A53ED 9027D831" \
"179727B0 865A8918 DA3EDBEB CF9B14ED 44CE6CBA CED4BB1B" \
"DB7F1447 E6CC254B 33205151 2BD7AF42 6FB8F401 378CD2BF" \
"5983CA01 C64B92EC F032EA15 D1721D03 F482D7CE 6E74FEF6" \
"D55E702F 46980C82 B5A84031 900B1C9E 59E7C97F BEC7E8F3" \
"23A97A7E 36CC88BE 0F1D45B7 FF585AC5 4BD407B2 2B4154AA" \
"CC8F6D7E BF48E1D8 14CC5ED2 0F8037E0 A79715EE F29BE328" \
"06A1D58B B7C5DA76 F550AA3D 8A1FBFF0 EB19CCB1 A313D55C" \
"DA56C9EC 2EF29632 387FE8D7 6E3C0468 043E8F66 3F4860EE" \
"12BF2D5B 0B7474D6 E694F91E 6DBE1159 74A3926F 12FEE5E4" \
"38777CB6 A932DF8C D8BEC4D0 73B931BA 3BC832B6 8D9DD300" \
"741FA7BF 8AFC47ED 2576F693 6BA42466 3AAB639C 5AE4F568" \
"3423B474 2BF1C978 238F16CB E39D652D E3FDB8BE FC848AD9" \
"22222E04 A4037C07 13EB57A8 1A23F0C7 3473FC64 6CEA306B" \
"4BCBC886 2F8385DD FA9D4B7F A2C087E8 79683303 ED5BDD3A" \
"062B3CF5 B3A278A6 6D2A13F8 3F44F82D DF310EE0 74AB6A36" \
"4597E899 A0255DC1 64F31CC5 0846851D F9AB4819 5DED7EA1" \
"B1D510BD 7EE74D73 FAF36BC3 1ECFA268 359046F4 EB879F92" \
"4009438B 481C6CD7 889A002E D5EE382B C9190DA6 FC026E47" \
"9558E447 5677E9AA 9E3050E2 765694DF C81F56E8 80B96E71" \
"60C980DD 98EDD3DF FFFFFFFF FFFFFFFF"
extern struct dhgroup dh_modp768;
extern struct dhgroup dh_modp1024;
extern struct dhgroup dh_modp1536;
extern struct dhgroup dh_modp2048;
extern struct dhgroup dh_modp3072;
extern struct dhgroup dh_modp4096;
extern struct dhgroup dh_modp6144;
extern struct dhgroup dh_modp8192;
#endif /* _DHGROUP_H */

View File

@ -0,0 +1,149 @@
/* $KAME: dnssec.c,v 1.2 2001/08/05 18:46:07 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#include "config.h"
#include <sys/types.h>
#include <sys/param.h>
#include <stdlib.h>
#include <string.h>
#include "var.h"
#include "vmbuf.h"
#include "misc.h"
#include "plog.h"
#include "debug.h"
#include "isakmp_var.h"
#include "isakmp.h"
#include "ipsec_doi.h"
#include "oakley.h"
#include "netdb_dnssec.h"
#include "strnames.h"
#include "dnssec.h"
#include "gcmalloc.h"
extern int h_errno;
cert_t *
dnssec_getcert(id)
vchar_t *id;
{
cert_t *cert = NULL;
struct certinfo *res = NULL;
struct ipsecdoi_id_b *id_b;
int type;
char *name = NULL;
int namelen;
int error;
id_b = (struct ipsecdoi_id_b *)id->v;
namelen = id->l - sizeof(*id_b);
name = racoon_malloc(namelen + 1);
if (!name) {
plog(LLV_ERROR, LOCATION, NULL,
"failed to get buffer.\n");
return NULL;
}
memcpy(name, id_b + 1, namelen);
name[namelen] = '\0';
switch (id_b->type) {
case IPSECDOI_ID_FQDN:
error = getcertsbyname(name, &res);
if (error != 0) {
plog(LLV_ERROR, LOCATION, NULL,
"getcertsbyname(\"%s\") failed.\n", name);
goto err;
}
break;
case IPSECDOI_ID_IPV4_ADDR:
case IPSECDOI_ID_IPV6_ADDR:
/* XXX should be processed to query PTR ? */
default:
plog(LLV_ERROR, LOCATION, NULL,
"inpropper ID type passed %s "
"though getcert method is dnssec.\n",
s_ipsecdoi_ident(id_b->type));
return NULL;
}
/* check response */
if (res->ci_next == NULL) {
plog(LLV_WARNING, LOCATION, NULL,
"not supported multiple CERT RR.\n");
}
switch (res->ci_type) {
case DNSSEC_TYPE_PKIX:
/* XXX is it enough condition to set this type ? */
type = ISAKMP_CERT_X509SIGN;
break;
default:
plog(LLV_ERROR, LOCATION, NULL,
"not supported CERT RR type %d.\n", res->ci_type);
goto err;
}
/* create cert holder */
cert = oakley_newcert();
if (cert == NULL) {
plog(LLV_ERROR, LOCATION, NULL,
"failed to get cert buffer.\n");
goto err;
}
cert->pl = vmalloc(res->ci_certlen + 1);
if (cert->pl == NULL) {
plog(LLV_ERROR, LOCATION, NULL,
"failed to get cert buffer.\n");
goto err;
}
memcpy(cert->pl->v + 1, res->ci_cert, res->ci_certlen);
cert->pl->v[0] = type;
cert->cert.v = cert->pl->v + 1;
cert->cert.l = cert->pl->l - 1;
plog(LLV_DEBUG, LOCATION, NULL, "created CERT payload:\n");
plogdump(LLV_DEBUG, cert->pl->v, cert->pl->l);
end:
if (res)
freecertinfo(res);
return cert;
err:
if (name)
racoon_free(name);
if (cert)
oakley_delcert(cert);
goto end;
}

View File

@ -0,0 +1,37 @@
/* $Id: dnssec.h,v 1.1.1.1 2005/02/12 11:11:51 manu Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#ifndef _DNSSEC_H
#define _DNSSEC_H
extern cert_t *dnssec_getcert __P((vchar_t *));
#endif /* _DNSSEC_H */

View File

@ -0,0 +1,106 @@
This document is derived from the KAME racoon FAQ. Some answers do not
apply to ipsec-tools (they are obsolete or not up to date). They are
tagged [KAME]
Q: With what other IKE/IPsec implementation racoon is known to be interoperable?
A: [KAME]
See "IMPLEMENTATION" document supplied with KAME kit, or:
http://www.kame.net/dev/cvsweb.cgi/kame/IMPLEMENTATION
As we have tested/got test reports in the past, and our end and
the other end may have changed their implemenations, we are not sure
if we can interoperate with them today (we hope them to interoperate,
but we are not sure).
Also note that, IKE interoperability highly depends on configuration
on both ends. You must configure both ends exactly the same.
Q: How can I make racoon interoperate with <IKE/IPsec implementation>?
A:
Configure both ends exactly the same. With just a tiny little
differnce, you will be in trouble.
Q: How to build racoon on my platform?
A:
As usual: configure && make && make install
ipsec-tools is also available as a package in the NetBSD pkgsrc
Q: Describe me the options to "configure".
A:
--enable-adminport:
Lets racoon to listen to racoon admin port, which is to
be contacted by racoonctl(8).
--enable-natt:
Enable NAT-Traversal. This needs kernel support, which is
available on Linux. On NetBSD, NAT-Traversal kernel support
has not been integrated yet, you can get it from here:
http://ipsec-tools.sourceforge.net/netbsd_nat-t.diff
If you live in a country where software patents are legal,
using NAT-Traversal might infringe a patent.
--enable-frag:
Enable IKE fragmentation, which is a workaround for
broken routers that drop fragmented packets
--enable-hybrid:
Enable hybrid authentication, and ISAKMP mode config and
Xauth as well. Note that plain Xauth (without hybrid auth)
is not implemented.
--with-libradius:
Enable the use of RADIUS with hybrid authentication on the
server side. RADIUS is used for authentication, configuration
and accounting.
--with-libpam:
Enable the use of PAM with hybrid authentication on the
server side. PAM can be used for authentication and accounting.
--enable-gssapi:
Enable GSS-API, for Kerberos V support.
--enable-stats:
Enable statistics logging function.
--enable-samode-unspec:
Enable to use unspecified a mode of SA.
--enable-ipv6:
Enable IPv6 support.
--with-kernel-headers:
Supply the location of Linux kernel headers.
--with-readline:
Support readline input (yes by default).
--with-openssl:
Specify OpenSSL directory.
--sysconfdir:
Where racoon config file goes. Default is /etc, which means
that racoon will look for /etc/racoon.conf
--localstatedir:
Where is the directory where racoon stores the control socket
(when using --enable-adminport). Default is /var, which
means racoon will use /var/racoon/racoon.sock
--prefix:
Where racoon gets installed.
Q: How can I get help?
A:
Always identify your operating system platforms, the versions you are
using (like "ipsec-tools-0.5"), and information to repeat the
problem. The more revelant information you supply, the better your
chances of getting help are. Useful informations include, depending
of the problem:
- version identification
- trace from racoon, taken by "racoon -d 0xffffffff"
(maximum debug level)
- configuration file you are using
- probabaly, tcpdump trace
http://orange.kame.net/dev/send-pr.html has the guideline.
If your question is not confidential, send your questions to:
<ipsec-tools-devel@lists.sourceforge.net>
If your question is confidential, send your questions to:
<ipsec-tools-core@lists.sourceforge.net>
Q: Other documents to look at?
A:
http://www.netbsd.org/Documentation/network/ipsec/
http://www.kame.net/
http://www.kame.net/newsletter/

View File

@ -0,0 +1 @@
See http://www.kame.net/newsletter/20001119b/

View File

@ -0,0 +1,106 @@
The gss-api authentication mechanism implementation for racoon was
based on the ietf draft draft-ietf-ipsec-isakmp-gss-auth-06.txt.
The implementation uses the Heimdal gss-api library, i.e. gss-api
on top of Kerberos 5. The Heimdal gss-api library had to be modified
to meet the requirements of using gss-api in a daemon. More specifically,
the gss_acquire_cred() call did not work for other cases than
GSS_C_NO_CREDENTIAL ("use default creds"). Daemons are often started
as root, and have no Kerberos 5 credentials, so racoon explicitly
needs to acquire its credentials. The usual method (already used
by login authentication daemons) in these situations is to add
a set of special credentials to be used. For example, authentication
by daemons concerned with login credentials, uses 'host/fqdn' as
its credential, where fqdn is the hostname on the interface that
is being used. These special credentials need to be extracted into
a local keytab from the kdc. The default value used in racoon
is 'ike/fqdn', but it can be overridden in the racoon config file.
The modification to the Heimdal gss-api library implements the
mechanism above. If a credential other than GSS_C_NO_CREDENTIAL
is specified to gss_acquire_cred(), it first looks in the default
credential cache if it its principal matches the desired credential.
If not, it extracts it from the default keytab file, and stores
it in a memory-based credential cache, part of the gss credential
structure.
The modifcations to racoon itself are as follows:
* The racoon.conf config file accepts a new keyword, "gssapi_id",
to be used inside a proposal specification. It specifies
a string (a Kerberos 5 principal in this case), specifying the
credential that racoon will try to acquire. The default value
is 'ike/fqdn', where fqdn is the hostname for the interface
being used for the exchange. If the id is not specified, no
GSS endpoint attribute will be specified in the first SA sent.
However, if the initiator does specify a GSS endpoint attribute,
racoon will always respond with its own GSS endpoint name
in the SA (the default one if not specified by this option).
* The racoon.conf file accepts "gssapi_krb" as authentication
method inside a proposal specification. The number used
for this method is 65001, which is a temporary number as
specified in the draft.
* The cftoken.l and cfparse.y source files were modified to
pick up the configuration options. The original sources
stored algorithms in bitmask, which unfortunately meant
that the maximum value was 32, clearly not enough for 65001.
After consulting with the author (sakane@kame.net), it turned
out that method was a leftover, and no longer needed. I replaced
it with plain integers.
* The gss-api specific code was concentrated as much as possible
in gssapi.c and gssapi.h. The code to call functions defined
in these files is conditional on HAVE_GSSAPI, except for the
config scan code. Specifying this flag on the compiler commandline
is conditional on the --enable-gssapi option to the configure
script.
* Racoon seems to want to send accepted SA proposals back to
the initiator in a verbatim fashion, leaving no room to
insert the (variable-length) GSS endpoint name attribute.
I worked around this by re-assembling the extracted SA
into a new SA if the gssapi_krb method is used, and the
initiator sent the name attribute. This scheme should
possibly be re-examined by the racoon maintainers, storing
the SAs (the transformations, to be more precise) in a different
fashion to allow for variable-length attributes to be
re-inserted would be a good change, but I considered it to be
beyond the scope of this project.
* The various state functions for aggressive and main mode
(in isakmp_agg.c and isakmp_ident.c respectively) were
changed to conditionally change their behavior if the
gssapi_krb method is specified.
This implementation tried to follow the specification in the ietf draft
as close as possible. However, it has not been tested against other
IKE daemon implementations. The only other one I know of is Windows 2000,
and it has some caveats. I attempted to be Windows 2000 compatible.
Should racoon be tried against Windows 2000, the gssapi_id option in
the config file must be used, as Windows 2000 expects the GSS endpoint
name to be sent at all times. I have my doubts as to the W2K compatibility,
because the spec describes the GSS endpoint name sent by W2K as
an unicode string 'xxx@domain', which doesn't seem to match the
required standard for gss-api + kerberos 5 (i.e. I am fairly certain
that such a string will be rejected by the Heimdal gss-api library, as it
is not a valid Kerberos 5 principal).
With the Heimdal gss-api implementation, the gssapi_krb authentication
method will only work in main mode. Aggressive mode does not allow
for the extra round-trips needed by gss_init_sec_context and
gss_accept_sec_context when mutual authentication is requested.
The draft specifies that the a fallback should be done to main mode,
through the return of INVALID-EXCHANGE-TYPE if it turns out that
the gss-api mechanisms needs more roundtrips. This is implemented.
Unfortunately, racoon does not seem to properly fall back to
its next mode, and this is not specific to the gssapi_krb method.
So, to avoid problems, only specify main mode in the config file.
-- Frank van der Linden <fvdl@wasabisystems.com>

View File

@ -0,0 +1,223 @@
/* $KAME: dump.c,v 1.3 2000/09/23 15:31:05 itojun Exp $ */
/*
* Copyright (C) 2000 WIDE Project.
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#include "config.h"
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/queue.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip6.h>
#include <netinet/udp.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#if TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# if HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
# endif
#endif
#include <netdb.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <pcap.h>
#include <fcntl.h>
#include "vmbuf.h"
/* copied from pcap-int.h */
struct pcap_timeval {
u_int32_t tv_sec; /* seconds */
u_int32_t tv_usec; /* microseconds */
};
struct pcap_sf_pkthdr {
struct pcap_timeval ts; /* time stamp */
u_int32_t caplen; /* length of portion present */
u_int32_t len; /* length this packet (off wire) */
};
#define TCPDUMP_MAGIC 0xa1b2c3d4
static int fd = -1;
int
isakmp_dump_open(path)
char *path;
{
struct pcap_file_header hdr;
path = "isakmp.dump";
if (fd >= 0)
return EBUSY;
fd = open(path, O_WRONLY|O_CREAT|O_APPEND, 0600);
if (fd < 0)
return errno;
memset(&hdr, 0, sizeof(hdr));
hdr.magic = TCPDUMP_MAGIC;
hdr.version_major = PCAP_VERSION_MAJOR;
hdr.version_minor = PCAP_VERSION_MINOR;
hdr.thiszone = 0;
hdr.snaplen = 60000; /* should be enough */
hdr.sigfigs = 0;
hdr.linktype = DLT_NULL;
if (write(fd, &hdr, sizeof(hdr)) != sizeof(hdr))
return errno;
return 0;
}
int
isakmp_dump_close()
{
close(fd);
fd = -1;
return 0;
}
int
isakmp_dump(msg, from, my)
vchar_t *msg;
struct sockaddr *from;
struct sockaddr *my;
{
struct ip ip;
#ifdef INET6
struct ip6_hdr ip6;
#endif
struct udphdr uh;
int32_t af; /*llhdr for DLT_NULL*/
struct pcap_sf_pkthdr sf_hdr;
struct timeval tv;
/* af validation */
if (from && my) {
if (from->sa_family == my->sa_family)
af = from->sa_family;
else
return EAFNOSUPPORT;
} else if (from)
af = from->sa_family;
else if (my)
af = my->sa_family;
else
af = AF_INET; /*assume it*/
switch (af) {
case AF_INET:
#ifdef INET6
case AF_INET6:
#endif
break;
default:
return EAFNOSUPPORT;
}
memset(&sf_hdr, 0, sizeof(sf_hdr));
gettimeofday(&tv, NULL);
sf_hdr.ts.tv_sec = tv.tv_sec;
sf_hdr.ts.tv_usec = tv.tv_usec;
/* write out timestamp and llhdr */
switch (af == AF_INET) {
case AF_INET:
sf_hdr.caplen = sf_hdr.len = sizeof(ip);
break;
case AF_INET6:
sf_hdr.caplen = sf_hdr.len = sizeof(ip6);
break;
}
sf_hdr.caplen += sizeof(af) + sizeof(uh) + msg->l;
sf_hdr.len += sizeof(af) + sizeof(uh) + msg->l;
if (write(fd, &sf_hdr, sizeof(sf_hdr)) < sizeof(sf_hdr))
return errno;
if (write(fd, &af, sizeof(af)) < sizeof(af))
return errno;
/* write out llhdr and ip header */
if (af == AF_INET) {
memset(&ip, 0, sizeof(ip));
ip.ip_v = IPVERSION;
ip.ip_hl = sizeof(ip) >> 2;
if (from)
ip.ip_src = ((struct sockaddr_in *)from)->sin_addr;
if (my)
ip.ip_dst = ((struct sockaddr_in *)my)->sin_addr;
ip.ip_p = IPPROTO_UDP;
ip.ip_ttl = 1;
ip.ip_len = htons(sizeof(ip) + sizeof(uh) + msg->l);
if (write(fd, &ip, sizeof(ip)) < sizeof(ip))
return errno;
} else if (af == AF_INET6) {
memset(&ip6, 0, sizeof(ip6));
ip6.ip6_vfc = IPV6_VERSION;
if (from)
ip6.ip6_src = ((struct sockaddr_in6 *)from)->sin6_addr;
if (my)
ip6.ip6_dst = ((struct sockaddr_in6 *)my)->sin6_addr;
ip6.ip6_nxt = IPPROTO_UDP;
ip6.ip6_plen = htons(sizeof(uh) + msg->l);
ip6.ip6_hlim = 1;
if (write(fd, &ip6, sizeof(ip6)) < sizeof(ip6))
return errno;
}
/* write out udp header */
memset(&uh, 0, sizeof(uh));
uh.uh_sport = htons(500);
uh.uh_dport = htons(500);
uh.uh_ulen = htons(msg->l & 0xffff);
uh.uh_sum = htons(0x0000); /*no checksum - invalid for IPv6*/
if (write(fd, &uh, sizeof(uh)) < sizeof(uh))
return errno;
/* write out payload */
if (write(fd, msg->v, msg->l) != msg->l)
return errno;
return 0;
}

View File

@ -0,0 +1,39 @@
/* $Id: dump.h,v 1.1.1.1 2005/02/12 11:11:53 manu Exp $ */
/*
* Copyright (C) 2000 WIDE Project.
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#ifndef _DUMP_H
#define _DUMP_H
extern int isakmp_dump_open __P((char *));
extern int isakmp_dump_close __P((void));
extern int isakmp_dump __P((vchar_t *, struct sockaddr *, struct sockaddr *));
#endif /* _DUMP_H */

File diff suppressed because it is too large Load Diff

133
crypto/dist/ipsec-tools/src/racoon/evt.c vendored Normal file
View File

@ -0,0 +1,133 @@
/* $Id: evt.c,v 1.1.1.1 2005/02/12 11:11:53 manu Exp $ */
/*
* Copyright (C) 2004 Emmanuel Dreyfus
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#include "config.h"
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/queue.h>
#include <sys/socket.h>
#include "vmbuf.h"
#include "plog.h"
#include "misc.h"
#include "gcmalloc.h"
#include "evt.h"
struct evtlist evtlist = TAILQ_HEAD_INITIALIZER(evtlist);
int evtlist_len = 0;
void
evt_push(src, dst, type, optdata)
struct sockaddr *src;
struct sockaddr *dst;
int type;
vchar_t *optdata;
{
struct evtdump *evtdump;
struct evt *evt;
size_t len;
len = sizeof(*evtdump);
if (optdata)
len += optdata->l;
if ((evtdump = racoon_malloc(len)) == NULL) {
plog(LLV_ERROR, LOCATION, NULL, "Cannot record event: %s\n",
strerror(errno));
return;
}
if ((evt = racoon_malloc(sizeof(*evt))) == NULL) {
plog(LLV_ERROR, LOCATION, NULL, "Cannot record event: %s\n",
strerror(errno));
racoon_free(evtdump);
return;
}
if (src)
memcpy(&evtdump->src, src, sysdep_sa_len(src));
if (dst)
memcpy(&evtdump->dst, dst, sysdep_sa_len(dst));
evtdump->len = len;
evtdump->type = type;
time(&evtdump->timestamp);
if (optdata)
memcpy(evtdump + 1, optdata->v, optdata->l);
evt->dump = evtdump;
TAILQ_INSERT_TAIL(&evtlist, evt, next);
if (evtlist_len++ == EVTLIST_MAX)
evt_push(NULL, NULL, EVTT_OVERFLOW, NULL);
return;
}
struct evtdump *
evt_pop(void) {
struct evtdump *evtdump;
struct evt *evt;
if ((evt = TAILQ_FIRST(&evtlist)) == NULL)
return NULL;
evtdump = evt->dump;
TAILQ_REMOVE(&evtlist, evt, next);
racoon_free(evt);
evtlist_len--;
return evtdump;
}
vchar_t *
evt_dump(void) {
struct evtdump *evtdump;
vchar_t *buf = NULL;
if ((evtdump = evt_pop()) != NULL) {
if ((buf = vmalloc(evtdump->len)) == NULL) {
plog(LLV_ERROR, LOCATION, NULL,
"evt_dump failed: %s\n", strerror(errno));
return NULL;
}
memcpy(buf->v, evtdump, evtdump->len);
racoon_free(evtdump);
}
return buf;
}

View File

@ -0,0 +1,84 @@
/* $Id: evt.h,v 1.1.1.1 2005/02/12 11:11:53 manu Exp $ */
/*
* Copyright (C) 2004 Emmanuel Dreyfus
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#ifndef _EVT_H
#define _EVT_H
struct evtdump {
size_t len;
struct sockaddr_storage src;
struct sockaddr_storage dst;
time_t timestamp;
int type;
/*
* Optionnal list of struct isakmp_data
* for type EVTT_ISAKMP_CFG_DONE
*/
};
/* type */
#define EVTT_UNSEPC 0
#define EVTT_PHASE1_UP 1
#define EVTT_PHASE1_DOWN 2
#define EVTT_XAUTH_SUCCESS 3
#define EVTT_ISAKMP_CFG_DONE 4
#define EVTT_PHASE2_UP 5
#define EVTT_PHASE2_DOWN 6
#define EVTT_DPD_TIMEOUT 7
#define EVTT_PEER_NO_RESPONSE 8
#define EVTT_PEER_DELETE 9
#define EVTT_RACOON_QUIT 10
#define EVTT_XAUTH_FAILED 11
#define EVTT_OVERFLOW 12 /* Event queue overflowed */
#define EVTT_PEERPH1AUTH_FAILED 13
struct evt {
struct evtdump *dump;
TAILQ_ENTRY(evt) next;
};
TAILQ_HEAD(evtlist, evt);
#define EVTLIST_MAX 32
#ifdef ENABLE_ADMINPORT
struct evtdump *evt_pop(void);
vchar_t *evt_dump(void);
void evt_push(struct sockaddr *, struct sockaddr *, int, vchar_t *);
#endif
#ifdef ENABLE_ADMINPORT
#define EVT_PUSH(src, dst, type, optdata) evt_push(src, dst, type, optdata);
#else
#define EVT_PUSH(src, dst, type, optdata) ;
#endif
#endif /* _EVT_H */

View File

@ -0,0 +1,114 @@
/* $KAME: gcmalloc.h,v 1.4 2001/11/16 04:34:57 sakane Exp $ */
/*
* Copyright (C) 2000, 2001 WIDE Project.
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
/*
* Debugging malloc glue for Racoon.
*/
#ifndef _GCMALLOC_H_DEFINED
#define _GCMALLOC_H_DEFINED
/* ElectricFence needs no special handling. */
/*
* Boehm-GC provides GC_malloc(), GC_realloc(), GC_free() functions,
* but not the traditional entry points. So what we do is provide
* malloc(), calloc(), realloc(), and free() entry points in the main
* program and letting the linker do the rest.
*/
#ifdef GC
#define GC_DEBUG
#include <gc.h>
#ifdef RACOON_MAIN_PROGRAM
void *
malloc(size_t size)
{
return (GC_MALLOC(size));
}
void *
calloc(size_t number, size_t size)
{
/* GC_malloc() clears the storage. */
return (GC_MALLOC(number * size));
}
void *
realloc(void *ptr, size_t size)
{
return (GC_REALLOC(ptr, size));
}
void
free(void *ptr)
{
GC_FREE(ptr);
}
#endif /* RACOON_MAIN_PROGRAM */
#define racoon_malloc(sz) GC_debug_malloc(sz, GC_EXTRAS)
#define racoon_calloc(cnt, sz) GC_debug_malloc(cnt * sz, GC_EXTRAS)
#define racoon_realloc(old, sz) GC_debug_realloc(old, sz, GC_EXTRAS)
#define racoon_free(p) GC_debug_free(p)
#endif /* GC */
/*
* Dmalloc only requires that you pull in a header file and link
* against libdmalloc.
*/
#ifdef DMALLOC
#include <dmalloc.h>
#endif /* DMALLOC */
#ifdef DEBUG_RECORD_MALLOCATION
#include <debugrm.h>
#else
#ifndef racoon_malloc
#define racoon_malloc(sz) malloc((sz))
#endif
#ifndef racoon_calloc
#define racoon_calloc(cnt, sz) calloc((cnt), (sz))
#endif
#ifndef racoon_realloc
#define racoon_realloc(old, sz) realloc((old), (sz))
#endif
#ifndef racoon_free
#define racoon_free(p) free((p))
#endif
#endif /* DEBUG_RECORD_MALLOCATION */
#endif /* _GCMALLOC_H_DEFINED */

View File

@ -0,0 +1,172 @@
/* $Id: genlist.c,v 1.1.1.1 2005/02/12 11:11:54 manu Exp $ */
/*
* Copyright (C) 2004 SuSE Linux AG, Nuernberg, Germany.
* Contributed by: Michal Ludvig <mludvig@suse.cz>, SUSE Labs
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/queue.h>
#include "genlist.h"
struct genlist *
genlist_init (void)
{
struct genlist *new = calloc(sizeof(struct genlist), 1);
TAILQ_INIT(new);
return new;
}
struct genlist_entry *
genlist_insert (struct genlist *head, void *data)
{
struct genlist_entry *entry = calloc(sizeof(struct genlist_entry), 1);
entry->data = data;
TAILQ_INSERT_HEAD(head, entry, chain);
return entry;
}
struct genlist_entry *
genlist_append (struct genlist *head, void *data)
{
struct genlist_entry *entry = calloc(sizeof(struct genlist_entry), 1);
entry->data = data;
TAILQ_INSERT_TAIL(head, entry, chain);
return entry;
}
void *
genlist_foreach (struct genlist *head, genlist_func_t func, void *arg)
{
struct genlist_entry *p;
void *ret = NULL;
TAILQ_FOREACH(p, head, chain) {
ret = (*func)(p->data, arg);
if (ret)
break;
}
return ret;
}
void *
genlist_next (struct genlist *head, struct genlist_entry **buf)
{
struct genlist_entry *p;
if (head)
p = TAILQ_FIRST(head);
else
p = (buf && *buf) ? TAILQ_NEXT(*buf, chain) : NULL;
if (buf)
*buf = p;
return (p ? p->data : NULL);
}
void
genlist_free (struct genlist *head, genlist_freedata_t func)
{
struct genlist_entry *p;
while ((p = TAILQ_LAST(head, genlist)) != NULL) {
TAILQ_REMOVE(head, p, chain);
if (func)
func(p->data);
free(p);
}
free(head);
}
#if 0
/* Here comes the example... */
struct conf {
struct genlist *l1, *l2;
};
void *
print_entry(void *entry, void *arg)
{
if (!entry)
return NULL;
printf("%s\n", (char *)entry);
return NULL;
}
void
dump_list(struct genlist *head)
{
genlist_foreach(head, print_entry, NULL);
}
void
free_data(void *data)
{
printf ("removing %s\n", (char *)data);
}
int main()
{
struct conf *cf;
char *cp;
struct genlist_entry *gpb;
cf = calloc(sizeof(struct conf), 1);
cf->l1 = genlist_init();
cf->l2 = genlist_init();
genlist_insert(cf->l1, "Ahoj");
genlist_insert(cf->l1, "Cau");
genlist_insert(cf->l1, "Nazdar");
genlist_insert(cf->l1, "Te buch");
genlist_append(cf->l2, "Curak");
genlist_append(cf->l2, "Kozy");
genlist_append(cf->l2, "Pica");
genlist_append(cf->l2, "Prdel");
printf("List 2\n");
dump_list(cf->l2);
printf("\nList 1\n");
dump_list(cf->l1);
printf("\nList 2 - using genlist_next()\n");
for (cp = genlist_next (cf->l2, &gpb); cp; cp = genlist_next (0, &gpb))
printf("%s\n", cp);
printf("\nFreeing List 1\n");
/* the data here isn't actually alloc'd so we would really call
* genlist_free (cf->l1, 0); but to illustrate the idea */
genlist_free (cf->l1, free_data);
cf->l1 = 0;
return 0;
}
#endif

View File

@ -0,0 +1,80 @@
/* $Id: genlist.h,v 1.1.1.1 2005/02/12 11:11:54 manu Exp $ */
/*
* Copyright (C) 2004 SuSE Linux AG, Nuernberg, Germany.
* Contributed by: Michal Ludvig <mludvig@suse.cz>, SUSE Labs
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#ifndef _GENLIST_H
#define _GENLIST_H
#include <sys/queue.h>
/* See the bottom of genlist.c for example use. */
/* This declares 'struct genlist' */
TAILQ_HEAD(genlist, genlist_entry);
/* This is where the data are actually stored. */
struct genlist_entry {
void *data;
TAILQ_ENTRY(genlist_entry) chain;
};
/* This function returns an initialized list head. */
struct genlist *genlist_init (void);
/* Insert an entry at the beginning/end og the list. */
struct genlist_entry *genlist_insert (struct genlist *head, void *data);
struct genlist_entry *genlist_append (struct genlist *head, void *data);
/* Create a function with this prototype for use with genlist_foreach().
* See genlist_foreach() description below for details. */
typedef void *(genlist_func_t)(void *entry, void *arg);
/* Traverse the list and call 'func' for each entry. As long as func() returns
* NULL the list traversal continues, once it returns non-NULL (usually the
* 'entry' arg), the list traversal exits and the return value is returned
* further from genlist_foreach(). Optional 'arg' may be passed to func(), e.g.
* for some lookup purposes, etc. */
void *genlist_foreach (struct genlist *head, genlist_func_t func, void *arg);
/* Get first entry in list if head is not NULL, otherwise get next
* entry based on saved position in list from previous call as stored in buf.
* If buf is NULL no position is saved */
void *genlist_next (struct genlist *head, struct genlist_entry **buf);
/* Create a function with this prototype for use with genlist_free()
* to free any storage associated with genlist_entry.data */
typedef void (genlist_freedata_t)(void *entry);
/* Free all storage associated with list at head using func to free any
* alloc()d data in data field of genlist_entry */
void genlist_free (struct genlist *head, genlist_freedata_t func);
#endif /* _GENLIST_H */

View File

@ -0,0 +1,412 @@
/* $KAME: getcertsbyname.c,v 1.7 2001/11/16 04:12:59 sakane Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#include "config.h"
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <resolv.h>
#ifdef HAVE_LWRES_GETRRSETBYNAME
#include <lwres/netdb.h>
#include <lwres/lwres.h>
#else
#include <netdb.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#ifdef DNSSEC_DEBUG
#include <stdio.h>
#include <strings.h>
#endif
#include "netdb_dnssec.h"
/* XXX should it use ci_errno to hold errno instead of h_errno ? */
extern int h_errno;
static struct certinfo *getnewci __P((int, int, int, int, int, char *));
static struct certinfo *
getnewci(qtype, keytag, algorithm, flags, certlen, cert)
int qtype, keytag, algorithm, flags, certlen;
char *cert;
{
struct certinfo *res;
res = malloc(sizeof(*res));
if (!res)
return NULL;
memset(res, 0, sizeof(*res));
res->ci_type = qtype;
res->ci_keytag = keytag;
res->ci_algorithm = algorithm;
res->ci_flags = flags;
res->ci_certlen = certlen;
res->ci_cert = malloc(certlen);
if (!res->ci_cert) {
free(res);
return NULL;
}
memcpy(res->ci_cert, cert, certlen);
return res;
}
void
freecertinfo(ci)
struct certinfo *ci;
{
struct certinfo *next;
do {
next = ci->ci_next;
if (ci->ci_cert)
free(ci->ci_cert);
free(ci);
ci = next;
} while (ci);
}
/*
* get CERT RR by FQDN and create certinfo structure chain.
*/
#ifdef HAVE_LWRES_GETRRSETBYNAME
#define getrrsetbyname lwres_getrrsetbyname
#define freerrset lwres_freerrset
#define hstrerror lwres_hstrerror
#endif
#if defined(HAVE_LWRES_GETRRSETBYNAME) || defined(AHVE_GETRRSETBYNAME)
int
getcertsbyname(name, res)
char *name;
struct certinfo **res;
{
int rdlength;
char *cp;
int type, keytag, algorithm;
struct certinfo head, *cur;
struct rrsetinfo *rr = NULL;
int i;
int error = -1;
/* initialize res */
*res = NULL;
memset(&head, 0, sizeof(head));
cur = &head;
error = getrrsetbyname(name, C_IN, T_CERT, 0, &rr);
if (error) {
#ifdef DNSSEC_DEBUG
printf("getrrsetbyname: %s\n", hstrerror(error));
#endif
h_errno = NO_RECOVERY;
goto end;
}
if (rr->rri_rdclass != C_IN
|| rr->rri_rdtype != T_CERT
|| rr->rri_nrdatas == 0) {
#ifdef DNSSEC_DEBUG
printf("getrrsetbyname: %s", hstrerror(error));
#endif
h_errno = NO_RECOVERY;
goto end;
}
#ifdef DNSSEC_DEBUG
if (!(rr->rri_flags & LWRDATA_VALIDATED))
printf("rr is not valid");
#endif
for (i = 0; i < rr->rri_nrdatas; i++) {
rdlength = rr->rri_rdatas[i].rdi_length;
cp = rr->rri_rdatas[i].rdi_data;
GETSHORT(type, cp); /* type */
rdlength -= INT16SZ;
GETSHORT(keytag, cp); /* key tag */
rdlength -= INT16SZ;
algorithm = *cp++; /* algorithm */
rdlength -= 1;
#ifdef DNSSEC_DEBUG
printf("type=%d keytag=%d alg=%d len=%d\n",
type, keytag, algorithm, rdlength);
#endif
/* create new certinfo */
cur->ci_next = getnewci(type, keytag, algorithm,
rr->rri_flags, rdlength, cp);
if (!cur->ci_next) {
#ifdef DNSSEC_DEBUG
printf("getnewci: %s", strerror(errno));
#endif
h_errno = NO_RECOVERY;
goto end;
}
cur = cur->ci_next;
}
*res = head.ci_next;
error = 0;
end:
if (rr)
freerrset(rr);
if (error && head.ci_next)
freecertinfo(head.ci_next);
return error;
}
#else /*!HAVE_LWRES_GETRRSETBYNAME*/
int
getcertsbyname(name, res)
char *name;
struct certinfo **res;
{
caddr_t answer = NULL, p;
int buflen, anslen, len;
HEADER *hp;
int qdcount, ancount, rdlength;
char *cp, *eom;
char hostbuf[1024]; /* XXX */
int qtype, qclass, keytag, algorithm;
struct certinfo head, *cur;
int error = -1;
/* initialize res */
*res = NULL;
memset(&head, 0, sizeof(head));
cur = &head;
/* get CERT RR */
buflen = 512;
do {
buflen *= 2;
p = realloc(answer, buflen);
if (!p) {
#ifdef DNSSEC_DEBUG
printf("realloc: %s", strerror(errno));
#endif
h_errno = NO_RECOVERY;
goto end;
}
answer = p;
anslen = res_query(name, C_IN, T_CERT, answer, buflen);
if (anslen == -1)
goto end;
} while (buflen < anslen);
#ifdef DNSSEC_DEBUG
printf("get a DNS packet len=%d\n", anslen);
#endif
/* parse CERT RR */
eom = answer + anslen;
hp = (HEADER *)answer;
qdcount = ntohs(hp->qdcount);
ancount = ntohs(hp->ancount);
/* question section */
if (qdcount != 1) {
#ifdef DNSSEC_DEBUG
printf("query count is not 1.\n");
#endif
h_errno = NO_RECOVERY;
goto end;
}
cp = (char *)(hp + 1);
len = dn_expand(answer, eom, cp, hostbuf, sizeof(hostbuf));
if (len < 0) {
#ifdef DNSSEC_DEBUG
printf("dn_expand failed.\n");
#endif
goto end;
}
cp += len;
GETSHORT(qtype, cp); /* QTYPE */
GETSHORT(qclass, cp); /* QCLASS */
/* answer section */
while (ancount-- && cp < eom) {
len = dn_expand(answer, eom, cp, hostbuf, sizeof(hostbuf));
if (len < 0) {
#ifdef DNSSEC_DEBUG
printf("dn_expand failed.\n");
#endif
goto end;
}
cp += len;
GETSHORT(qtype, cp); /* TYPE */
GETSHORT(qclass, cp); /* CLASS */
cp += INT32SZ; /* TTL */
GETSHORT(rdlength, cp); /* RDLENGTH */
/* CERT RR */
if (qtype != T_CERT) {
#ifdef DNSSEC_DEBUG
printf("not T_CERT\n");
#endif
h_errno = NO_RECOVERY;
goto end;
}
GETSHORT(qtype, cp); /* type */
rdlength -= INT16SZ;
GETSHORT(keytag, cp); /* key tag */
rdlength -= INT16SZ;
algorithm = *cp++; /* algorithm */
rdlength -= 1;
if (cp + rdlength > eom) {
#ifdef DNSSEC_DEBUG
printf("rdlength is too long.\n");
#endif
h_errno = NO_RECOVERY;
goto end;
}
#ifdef DNSSEC_DEBUG
printf("type=%d keytag=%d alg=%d len=%d\n",
qtype, keytag, algorithm, rdlength);
#endif
/* create new certinfo */
cur->ci_next = getnewci(qtype, keytag, algorithm,
0, rdlength, cp);
if (!cur->ci_next) {
#ifdef DNSSEC_DEBUG
printf("getnewci: %s", strerror(errno));
#endif
h_errno = NO_RECOVERY;
goto end;
}
cur = cur->ci_next;
cp += rdlength;
}
*res = head.ci_next;
error = 0;
end:
if (answer)
free(answer);
if (error && head.ci_next)
freecertinfo(head.ci_next);
return error;
}
#endif
#ifdef DNSSEC_DEBUG
int
b64encode(p, len)
char *p;
int len;
{
static const char b64t[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/=";
while (len > 2) {
printf("%c", b64t[(p[0] >> 2) & 0x3f]);
printf("%c", b64t[((p[0] << 4) & 0x30) | ((p[1] >> 4) & 0x0f)]);
printf("%c", b64t[((p[1] << 2) & 0x3c) | ((p[2] >> 6) & 0x03)]);
printf("%c", b64t[p[2] & 0x3f]);
len -= 3;
p += 3;
}
if (len == 2) {
printf("%c", b64t[(p[0] >> 2) & 0x3f]);
printf("%c", b64t[((p[0] << 4) & 0x30)| ((p[1] >> 4) & 0x0f)]);
printf("%c", b64t[((p[1] << 2) & 0x3c)]);
printf("%c", '=');
} else if (len == 1) {
printf("%c", b64t[(p[0] >> 2) & 0x3f]);
printf("%c", b64t[((p[0] << 4) & 0x30)]);
printf("%c", '=');
printf("%c", '=');
}
return 0;
}
int
main(ac, av)
int ac;
char **av;
{
struct certinfo *res, *p;
int i;
if (ac < 2) {
printf("Usage: a.out (FQDN)\n");
exit(1);
}
i = getcertsbyname(*(av + 1), &res);
if (i != 0) {
herror("getcertsbyname");
exit(1);
}
printf("getcertsbyname succeeded.\n");
i = 0;
for (p = res; p; p = p->ci_next) {
printf("certinfo[%d]:\n", i);
printf("\tci_type=%d\n", p->ci_type);
printf("\tci_keytag=%d\n", p->ci_keytag);
printf("\tci_algorithm=%d\n", p->ci_algorithm);
printf("\tci_flags=%d\n", p->ci_flags);
printf("\tci_certlen=%d\n", p->ci_certlen);
printf("\tci_cert: ");
b64encode(p->ci_cert, p->ci_certlen);
printf("\n");
i++;
}
freecertinfo(res);
exit(0);
}
#endif

View File

@ -0,0 +1,44 @@
/* $Id: gnuc.h,v 1.1.1.1 2005/02/12 11:11:57 manu Exp $ */
/* Define __P() macro, if necessary */
#undef __P
#ifndef __P
#if __STDC__
#define __P(protos) protos
#else
#define __P(protos) ()
#endif
#endif
/* inline foo */
#ifdef __GNUC__
#define inline __inline
#else
#define inline
#endif
/*
* Handle new and old "dead" routine prototypes
*
* For example:
*
* __dead void foo(void) __attribute__((volatile));
*
*/
#ifdef __GNUC__
#ifndef __dead
#define __dead volatile
#endif
#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)
#ifndef __attribute__
#define __attribute__(args)
#endif
#endif
#else
#ifndef __dead
#define __dead
#endif
#ifndef __attribute__
#define __attribute__(args)
#endif
#endif

View File

@ -0,0 +1,922 @@
/* $Id: grabmyaddr.c,v 1.1.1.1 2005/02/12 11:11:57 manu Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#include "config.h"
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#if defined(__FreeBSD__) && __FreeBSD__ >= 3
#include <net/if_var.h>
#endif
#if defined(__NetBSD__) || defined(__FreeBSD__)
#include <netinet/in.h>
#include <netinet6/in6_var.h>
#endif
#include <net/route.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <netdb.h>
#ifdef HAVE_GETIFADDRS
#include <ifaddrs.h>
#include <net/if.h>
#endif
#include "var.h"
#include "misc.h"
#include "vmbuf.h"
#include "plog.h"
#include "sockmisc.h"
#include "debug.h"
#include "localconf.h"
#include "handler.h"
#include "grabmyaddr.h"
#include "sockmisc.h"
#include "isakmp_var.h"
#include "gcmalloc.h"
#include "nattraversal.h"
#ifdef __linux__
#include <linux/types.h>
#include <linux/rtnetlink.h>
#ifndef HAVE_GETIFADDRS
#define HAVE_GETIFADDRS
#define NEED_LINUX_GETIFADDRS
#endif
#endif
#ifndef HAVE_GETIFADDRS
static unsigned int if_maxindex __P((void));
#endif
static struct myaddrs *find_myaddr __P((struct myaddrs *, struct myaddrs *));
static int suitable_ifaddr __P((const char *, const struct sockaddr *));
#ifdef INET6
static int suitable_ifaddr6 __P((const char *, const struct sockaddr *));
#endif
#ifdef NEED_LINUX_GETIFADDRS
/* We could do this _much_ better. kame racoon in its current form
* will esentially die at frequent changes of address configuration.
*/
struct ifaddrs
{
struct ifaddrs *ifa_next;
char ifa_name[16];
int ifa_ifindex;
struct sockaddr *ifa_addr;
struct sockaddr_storage ifa_addrbuf;
};
static int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len)
{
while (RTA_OK(rta, len)) {
if (rta->rta_type <= max)
tb[rta->rta_type] = rta;
rta = RTA_NEXT(rta,len);
}
return 0;
}
static void recvaddrs(int fd, struct ifaddrs **ifa, __u32 seq)
{
char buf[8192];
struct sockaddr_nl nladdr;
struct iovec iov = { buf, sizeof(buf) };
struct ifaddrmsg *m;
struct rtattr * rta_tb[IFA_MAX+1];
struct ifaddrs *I;
while (1) {
int status;
struct nlmsghdr *h;
struct msghdr msg = {
(void*)&nladdr, sizeof(nladdr),
&iov, 1,
NULL, 0,
0
};
status = recvmsg(fd, &msg, 0);
if (status < 0)
continue;
if (status == 0)
return;
if (nladdr.nl_pid) /* Message not from kernel */
continue;
h = (struct nlmsghdr*)buf;
while (NLMSG_OK(h, status)) {
if (h->nlmsg_seq != seq)
goto skip_it;
if (h->nlmsg_type == NLMSG_DONE)
return;
if (h->nlmsg_type == NLMSG_ERROR)
return;
if (h->nlmsg_type != RTM_NEWADDR)
goto skip_it;
m = NLMSG_DATA(h);
if (m->ifa_family != AF_INET &&
m->ifa_family != AF_INET6)
goto skip_it;
if (m->ifa_flags&IFA_F_TENTATIVE)
goto skip_it;
memset(rta_tb, 0, sizeof(rta_tb));
parse_rtattr(rta_tb, IFA_MAX, IFA_RTA(m), h->nlmsg_len - NLMSG_LENGTH(sizeof(*m)));
if (rta_tb[IFA_LOCAL] == NULL)
rta_tb[IFA_LOCAL] = rta_tb[IFA_ADDRESS];
if (rta_tb[IFA_LOCAL] == NULL)
goto skip_it;
I = malloc(sizeof(struct ifaddrs));
if (!I)
return;
memset(I, 0, sizeof(*I));
I->ifa_ifindex = m->ifa_index;
I->ifa_addr = (struct sockaddr*)&I->ifa_addrbuf;
I->ifa_addr->sa_family = m->ifa_family;
if (m->ifa_family == AF_INET) {
struct sockaddr_in *sin = (void*)I->ifa_addr;
memcpy(&sin->sin_addr, RTA_DATA(rta_tb[IFA_LOCAL]), 4);
} else {
struct sockaddr_in6 *sin = (void*)I->ifa_addr;
memcpy(&sin->sin6_addr, RTA_DATA(rta_tb[IFA_LOCAL]), 16);
if (IN6_IS_ADDR_LINKLOCAL(&sin->sin6_addr))
sin->sin6_scope_id = I->ifa_ifindex;
}
I->ifa_next = *ifa;
*ifa = I;
skip_it:
h = NLMSG_NEXT(h, status);
}
if (msg.msg_flags & MSG_TRUNC)
continue;
}
return;
}
static int getifaddrs(struct ifaddrs **ifa0)
{
struct {
struct nlmsghdr nlh;
struct rtgenmsg g;
} req;
struct sockaddr_nl nladdr;
static __u32 seq;
struct ifaddrs *i;
int fd;
fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
if (fd < 0)
return -1;
memset(&nladdr, 0, sizeof(nladdr));
nladdr.nl_family = AF_NETLINK;
req.nlh.nlmsg_len = sizeof(req);
req.nlh.nlmsg_type = RTM_GETADDR;
req.nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST;
req.nlh.nlmsg_pid = 0;
req.nlh.nlmsg_seq = ++seq;
req.g.rtgen_family = AF_UNSPEC;
if (sendto(fd, (void*)&req, sizeof(req), 0, (struct sockaddr*)&nladdr, sizeof(nladdr)) < 0) {
close(fd);
return -1;
}
*ifa0 = NULL;
recvaddrs(fd, ifa0, seq);
close(fd);
fd = socket(AF_INET, SOCK_DGRAM, 0);
for (i=*ifa0; i; i = i->ifa_next) {
struct ifreq ifr;
ifr.ifr_ifindex = i->ifa_ifindex;
ioctl(fd, SIOCGIFNAME, (void*)&ifr);
memcpy(i->ifa_name, ifr.ifr_name, 16);
}
return 0;
}
static void freeifaddrs(struct ifaddrs *ifa0)
{
struct ifaddrs *i;
while (ifa0) {
i = ifa0;
ifa0 = i->ifa_next;
free(i);
}
}
#endif
#ifndef HAVE_GETIFADDRS
static unsigned int
if_maxindex()
{
struct if_nameindex *p, *p0;
unsigned int max = 0;
p0 = if_nameindex();
for (p = p0; p && p->if_index && p->if_name; p++) {
if (max < p->if_index)
max = p->if_index;
}
if_freenameindex(p0);
return max;
}
#endif
void
clear_myaddr(db)
struct myaddrs **db;
{
struct myaddrs *p;
while (*db) {
p = (*db)->next;
delmyaddr(*db);
*db = p;
}
}
static struct myaddrs *
find_myaddr(db, p)
struct myaddrs *db;
struct myaddrs *p;
{
struct myaddrs *q;
char h1[NI_MAXHOST], h2[NI_MAXHOST];
if (getnameinfo(p->addr, sysdep_sa_len(p->addr), h1, sizeof(h1), NULL, 0,
NI_NUMERICHOST | niflags) != 0)
return NULL;
for (q = db; q; q = q->next) {
if (p->addr->sa_family != q->addr->sa_family)
continue;
if (getnameinfo(q->addr, sysdep_sa_len(q->addr), h2, sizeof(h2),
NULL, 0, NI_NUMERICHOST | niflags) != 0)
return NULL;
if (strcmp(h1, h2) == 0)
return q;
}
return NULL;
}
void
grab_myaddrs()
{
#ifdef HAVE_GETIFADDRS
struct myaddrs *p, *q, *old;
struct ifaddrs *ifa0, *ifap;
#ifdef INET6
struct sockaddr_in6 *sin6;
#endif
char addr1[NI_MAXHOST];
if (getifaddrs(&ifa0)) {
plog(LLV_ERROR, LOCATION, NULL,
"getifaddrs failed: %s\n", strerror(errno));
exit(1);
/*NOTREACHED*/
}
old = lcconf->myaddrs;
for (ifap = ifa0; ifap; ifap = ifap->ifa_next) {
if (! ifap->ifa_addr)
continue;
if (ifap->ifa_addr->sa_family != AF_INET
#ifdef INET6
&& ifap->ifa_addr->sa_family != AF_INET6
#endif
)
continue;
if (!suitable_ifaddr(ifap->ifa_name, ifap->ifa_addr)) {
plog(LLV_ERROR, LOCATION, NULL,
"unsuitable address: %s %s\n",
ifap->ifa_name,
saddrwop2str(ifap->ifa_addr));
continue;
}
p = newmyaddr();
if (p == NULL) {
exit(1);
/*NOTREACHED*/
}
p->addr = dupsaddr(ifap->ifa_addr);
if (p->addr == NULL) {
exit(1);
/*NOTREACHED*/
}
#ifdef INET6
#ifdef __KAME__
if (ifap->ifa_addr->sa_family == AF_INET6) {
sin6 = (struct sockaddr_in6 *)p->addr;
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)
|| IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) {
sin6->sin6_scope_id =
ntohs(*(u_int16_t *)&sin6->sin6_addr.s6_addr[2]);
sin6->sin6_addr.s6_addr[2] = 0;
sin6->sin6_addr.s6_addr[3] = 0;
}
}
#else /* !__KAME__ */
if (ifap->ifa_addr->sa_family == AF_INET6) {
sin6 = (struct sockaddr_in6 *)p->addr;
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)
|| IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) {
sin6->sin6_scope_id =
if_nametoindex(ifap->ifa_name);
}
}
#endif
#endif
if (getnameinfo(p->addr, sysdep_sa_len(p->addr),
addr1, sizeof(addr1),
NULL, 0,
NI_NUMERICHOST | niflags))
strlcpy(addr1, "(invalid)", sizeof(addr1));
plog(LLV_DEBUG, LOCATION, NULL,
"my interface: %s (%s)\n",
addr1, ifap->ifa_name);
q = find_myaddr(old, p);
if (q)
p->sock = q->sock;
else
p->sock = -1;
p->next = lcconf->myaddrs;
lcconf->myaddrs = p;
}
freeifaddrs(ifa0);
clear_myaddr(&old);
#else /*!HAVE_GETIFADDRS*/
int s;
unsigned int maxif;
int len;
struct ifreq *iflist;
struct ifconf ifconf;
struct ifreq *ifr, *ifr_end;
struct myaddrs *p, *q, *old;
#ifdef INET6
#ifdef __KAME__
struct sockaddr_in6 *sin6;
#endif
#endif
char addr1[NI_MAXHOST];
maxif = if_maxindex() + 1;
len = maxif * sizeof(struct sockaddr_storage) * 4; /* guess guess */
iflist = (struct ifreq *)racoon_malloc(len);
if (!iflist) {
plog(LLV_ERROR, LOCATION, NULL,
"failed to allocate buffer\n");
exit(1);
/*NOTREACHED*/
}
if ((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
plog(LLV_ERROR, LOCATION, NULL,
"socket(SOCK_DGRAM) failed: %s\n",
strerror(errno));
exit(1);
/*NOTREACHED*/
}
memset(&ifconf, 0, sizeof(ifconf));
ifconf.ifc_req = iflist;
ifconf.ifc_len = len;
if (ioctl(s, SIOCGIFCONF, &ifconf) < 0) {
plog(LLV_ERROR, LOCATION, NULL,
"ioctl(SIOCGIFCONF) failed: %s\n",
strerror(errno));
exit(1);
/*NOTREACHED*/
}
close(s);
old = lcconf->myaddrs;
/* Look for this interface in the list */
ifr_end = (struct ifreq *) (ifconf.ifc_buf + ifconf.ifc_len);
#define _IFREQ_LEN(p) \
(sizeof((p)->ifr_name) + sysdep_sa_len(&(p)->ifr_addr) > sizeof(struct ifreq) \
? sizeof((p)->ifr_name) + sysdep_sa_len(&(p)->ifr_addr) : sizeof(struct ifreq))
for (ifr = ifconf.ifc_req;
ifr < ifr_end;
ifr = (struct ifreq *)((caddr_t)ifr + _IFREQ_LEN(ifr))) {
switch (ifr->ifr_addr.sa_family) {
case AF_INET:
#ifdef INET6
case AF_INET6:
#endif
if (!suitable_ifaddr(ifr->ifr_name, &ifr->ifr_addr)) {
plog(LLV_ERROR, LOCATION, NULL,
"unsuitable address: %s %s\n",
ifr->ifr_name,
saddrwop2str(&ifr->ifr_addr));
continue;
}
p = newmyaddr();
if (p == NULL) {
exit(1);
/*NOTREACHED*/
}
p->addr = dupsaddr(&ifr->ifr_addr);
if (p->addr == NULL) {
exit(1);
/*NOTREACHED*/
}
#ifdef INET6
#ifdef __KAME__
sin6 = (struct sockaddr_in6 *)p->addr;
if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)
|| IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) {
sin6->sin6_scope_id =
ntohs(*(u_int16_t *)&sin6->sin6_addr.s6_addr[2]);
sin6->sin6_addr.s6_addr[2] = 0;
sin6->sin6_addr.s6_addr[3] = 0;
}
#endif
#endif
if (getnameinfo(p->addr, sysdep_sa_len(p->addr),
addr1, sizeof(addr1),
NULL, 0,
NI_NUMERICHOST | niflags))
strlcpy(addr1, "(invalid)", sizeof(addr1));
plog(LLV_DEBUG, LOCATION, NULL,
"my interface: %s (%s)\n",
addr1, ifr->ifr_name);
q = find_myaddr(old, p);
if (q)
p->sock = q->sock;
else
p->sock = -1;
p->next = lcconf->myaddrs;
lcconf->myaddrs = p;
break;
default:
break;
}
}
clear_myaddr(&old);
racoon_free(iflist);
#endif /*HAVE_GETIFADDRS*/
}
/*
* check the interface is suitable or not
*/
static int
suitable_ifaddr(ifname, ifaddr)
const char *ifname;
const struct sockaddr *ifaddr;
{
#ifdef ENABLE_HYBRID
/* Exclude any address we got through ISAKMP mode config */
if (exclude_cfg_addr(ifaddr) == 0)
return 0;
#endif
switch(ifaddr->sa_family) {
case AF_INET:
return 1;
#ifdef INET6
case AF_INET6:
return suitable_ifaddr6(ifname, ifaddr);
#endif
default:
return 0;
}
/*NOTREACHED*/
}
#ifdef INET6
static int
suitable_ifaddr6(ifname, ifaddr)
const char *ifname;
const struct sockaddr *ifaddr;
{
#ifndef __linux__
struct in6_ifreq ifr6;
int s;
#endif
if (ifaddr->sa_family != AF_INET6)
return 0;
#ifndef __linux__
s = socket(PF_INET6, SOCK_DGRAM, 0);
if (s == -1) {
plog(LLV_ERROR, LOCATION, NULL,
"socket(SOCK_DGRAM) failed:%s\n", strerror(errno));
return 0;
}
memset(&ifr6, 0, sizeof(ifr6));
strncpy(ifr6.ifr_name, ifname, strlen(ifname));
ifr6.ifr_addr = *(const struct sockaddr_in6 *)ifaddr;
if (ioctl(s, SIOCGIFAFLAG_IN6, &ifr6) < 0) {
plog(LLV_ERROR, LOCATION, NULL,
"ioctl(SIOCGIFAFLAG_IN6) failed:%s\n", strerror(errno));
close(s);
return 0;
}
close(s);
if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_DUPLICATED
|| ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_DETACHED
|| ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_ANYCAST)
return 0;
#endif
/* suitable */
return 1;
}
#endif
int
update_myaddrs()
{
#ifdef __linux__
char msg[BUFSIZ];
int len;
struct nlmsghdr *h = (void*)msg;
len = read(lcconf->rtsock, msg, sizeof(msg));
if (len < 0)
return errno == ENOBUFS;
if (len < sizeof(*h))
return 0;
if (h->nlmsg_pid) /* not from kernel! */
return 0;
if (h->nlmsg_type == RTM_NEWLINK)
return 0;
plog(LLV_DEBUG, LOCATION, NULL,
"netlink signals update interface address list\n");
return 1;
#else
char msg[BUFSIZ];
int len;
struct rt_msghdr *rtm;
len = read(lcconf->rtsock, msg, sizeof(msg));
if (len < 0) {
plog(LLV_ERROR, LOCATION, NULL,
"read(PF_ROUTE) failed: %s\n",
strerror(errno));
return 0;
}
rtm = (struct rt_msghdr *)msg;
if (len < rtm->rtm_msglen) {
plog(LLV_ERROR, LOCATION, NULL,
"read(PF_ROUTE) short read\n");
return 0;
}
if (rtm->rtm_version != RTM_VERSION) {
plog(LLV_ERROR, LOCATION, NULL,
"routing socket version mismatch\n");
close(lcconf->rtsock);
lcconf->rtsock = -1;
return 0;
}
switch (rtm->rtm_type) {
case RTM_NEWADDR:
case RTM_DELADDR:
case RTM_DELETE:
case RTM_IFINFO:
break;
case RTM_MISS:
/* ignore this message silently */
return 0;
default:
plog(LLV_DEBUG, LOCATION, NULL,
"msg %d not interesting\n", rtm->rtm_type);
return 0;
}
/* XXX more filters here? */
plog(LLV_DEBUG, LOCATION, NULL,
"caught rtm:%d, need update interface address list\n",
rtm->rtm_type);
return 1;
#endif /* __linux__ */
}
/*
* initialize default port for ISAKMP to send, if no "listen"
* directive is specified in config file.
*
* DO NOT listen to wildcard addresses. if you receive packets to
* wildcard address, you'll be in trouble (DoS attack possible by
* broadcast storm).
*/
int
autoconf_myaddrsport()
{
struct myaddrs *p;
int n;
plog(LLV_DEBUG, LOCATION, NULL,
"configuring default isakmp port.\n");
#ifdef ENABLE_NATT
if (natt_enabled_in_rmconf ()) {
plog(LLV_NOTIFY, LOCATION, NULL, "NAT-T is enabled, autoconfiguring ports\n");
for (p = lcconf->myaddrs; p; p = p->next) {
struct myaddrs *new;
if (! p->udp_encap) {
new = dupmyaddr(p);
new->udp_encap = 1;
}
}
}
#endif
for (p = lcconf->myaddrs, n = 0; p; p = p->next, n++) {
set_port (p->addr, p->udp_encap ? lcconf->port_isakmp_natt : lcconf->port_isakmp);
}
plog(LLV_DEBUG, LOCATION, NULL,
"%d addrs are configured successfully\n", n);
return 0;
}
/*
* get a port number to which racoon binded.
* NOTE: network byte order returned.
*/
u_short
getmyaddrsport(local)
struct sockaddr *local;
{
struct myaddrs *p, *bestmatch = NULL;
u_short bestmatch_port = PORT_ISAKMP;
/* get a relative port */
for (p = lcconf->myaddrs; p; p = p->next) {
if (!p->addr)
continue;
if (!cmpsaddrwop(local, p->addr)) {
if (! bestmatch) {
bestmatch = p;
continue;
}
switch (p->addr->sa_family) {
case AF_INET:
if (((struct sockaddr_in *)p->addr)->sin_port == PORT_ISAKMP) {
bestmatch = p;
bestmatch_port = ((struct sockaddr_in *)p->addr)->sin_port;
break;
}
break;
#ifdef INET6
case AF_INET6:
if (((struct sockaddr_in6 *)p->addr)->sin6_port == PORT_ISAKMP) {
bestmatch = p;
bestmatch_port = ((struct sockaddr_in6 *)p->addr)->sin6_port;
break;
}
break;
#endif
default:
plog(LLV_ERROR, LOCATION, NULL,
"unsupported AF %d\n", p->addr->sa_family);
continue;
}
}
}
return htons(bestmatch_port);
}
struct myaddrs *
newmyaddr()
{
struct myaddrs *new;
new = racoon_calloc(1, sizeof(*new));
if (new == NULL) {
plog(LLV_ERROR, LOCATION, NULL,
"failed to allocate buffer for myaddrs.\n");
return NULL;
}
new->next = NULL;
new->addr = NULL;
return new;
}
struct myaddrs *
dupmyaddr(struct myaddrs *old)
{
struct myaddrs *new;
new = racoon_calloc(1, sizeof(*new));
if (new == NULL) {
plog(LLV_ERROR, LOCATION, NULL,
"failed to allocate buffer for myaddrs.\n");
return NULL;
}
/* Copy the whole structure and set the differences. */
memcpy (new, old, sizeof (*new));
new->addr = dupsaddr (old->addr);
new->next = old->next;
old->next = new;
return new;
}
void
insmyaddr(new, head)
struct myaddrs *new;
struct myaddrs **head;
{
new->next = *head;
*head = new;
}
void
delmyaddr(myaddr)
struct myaddrs *myaddr;
{
if (myaddr->addr)
racoon_free(myaddr->addr);
racoon_free(myaddr);
}
int
initmyaddr()
{
/* initialize routing socket */
lcconf->rtsock = socket(PF_ROUTE, SOCK_RAW, PF_UNSPEC);
if (lcconf->rtsock < 0) {
plog(LLV_ERROR, LOCATION, NULL,
"socket(PF_ROUTE) failed: %s",
strerror(errno));
return -1;
}
#ifdef __linux__
{
struct sockaddr_nl nl;
int addr_len;
memset(&nl, 0, sizeof(nl));
nl.nl_family = AF_NETLINK;
nl.nl_groups = RTMGRP_IPV4_IFADDR|RTMGRP_LINK;
if (bind(lcconf->rtsock, (struct sockaddr*)&nl, sizeof(nl)) < 0) {
plog(LLV_ERROR, LOCATION, NULL,
"bind(PF_NETLINK) failed: %s\n",
strerror(errno));
return -1;
}
addr_len = sizeof(nl);
if (getsockname(lcconf->rtsock, (struct sockaddr*)&nl, &addr_len) < 0) {
plog(LLV_ERROR, LOCATION, NULL,
"getsockname(PF_NETLINK) failed: %s\n",
strerror(errno));
return -1;
}
}
#endif
if (lcconf->myaddrs == NULL && lcconf->autograbaddr == 1) {
grab_myaddrs();
if (autoconf_myaddrsport() < 0)
return -1;
}
return 0;
}
/* select the socket to be sent */
/* should implement other method. */
int
getsockmyaddr(my)
struct sockaddr *my;
{
struct myaddrs *p, *lastresort = NULL;
#if defined(INET6) && defined(__linux__)
struct myaddrs *match_wo_scope_id = NULL;
int check_wo_scope_id = (my->sa_family == AF_INET6) &&
IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6 *)my)->sin6_addr);
#endif
for (p = lcconf->myaddrs; p; p = p->next) {
if (p->addr == NULL)
continue;
if (my->sa_family == p->addr->sa_family) {
lastresort = p;
} else continue;
if (sysdep_sa_len(my) == sysdep_sa_len(p->addr)
&& memcmp(my, p->addr, sysdep_sa_len(my)) == 0) {
break;
}
#if defined(INET6) && defined(__linux__)
if (check_wo_scope_id && IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6 *)p->addr)->sin6_addr) &&
/* XXX: this depends on sin6_scope_id to be last
* item in struct sockaddr_in6 */
memcmp(my, p->addr,
sysdep_sa_len(my) - sizeof(uint32_t)) == 0) {
match_wo_scope_id = p;
}
#endif
}
#if defined(INET6) && defined(__linux__)
if (!p)
p = match_wo_scope_id;
#endif
if (!p)
p = lastresort;
if (!p) {
plog(LLV_ERROR, LOCATION, NULL,
"no socket matches address family %d\n",
my->sa_family);
return -1;
}
return p->sock;
}

View File

@ -0,0 +1,54 @@
/* $Id: grabmyaddr.h,v 1.1.1.1 2005/02/12 11:11:59 manu Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#ifndef _GRABMYADDR_H
#define _GRABMYADDR_H
struct myaddrs {
struct myaddrs *next;
struct sockaddr *addr;
int sock;
int udp_encap;
};
extern void clear_myaddr __P((struct myaddrs **));
extern void grab_myaddrs __P((void));
extern int update_myaddrs __P((void));
extern int autoconf_myaddrsport __P((void));
extern u_short getmyaddrsport __P((struct sockaddr *));
extern struct myaddrs *newmyaddr __P((void));
extern struct myaddrs *dupmyaddr __P((struct myaddrs *));
extern void insmyaddr __P((struct myaddrs *, struct myaddrs **));
extern void delmyaddr __P((struct myaddrs *));
extern int initmyaddr __P((void));
extern int getsockmyaddr __P((struct sockaddr *));
#endif /* _GRABMYADDR_H */

View File

@ -0,0 +1,745 @@
/* $KAME: gssapi.c,v 1.19 2001/04/03 15:51:55 thorpej Exp $ */
/*
* Copyright 2000 Wasabi Systems, Inc.
* All rights reserved.
*
* This software was written by Frank van der Linden of Wasabi Systems
* for Zembu Labs, Inc. http://www.zembu.com/
*
* 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.
* 3. The name of Wasabi Systems, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
* 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.
*/
#include "config.h"
#ifdef HAVE_GSSAPI
#include <sys/types.h>
#include <sys/queue.h>
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "var.h"
#include "misc.h"
#include "vmbuf.h"
#include "plog.h"
#include "sockmisc.h"
#include "schedule.h"
#include "debug.h"
#include "localconf.h"
#include "remoteconf.h"
#include "isakmp_var.h"
#include "isakmp.h"
#include "oakley.h"
#include "handler.h"
#include "ipsec_doi.h"
#include "crypto_openssl.h"
#include "pfkey.h"
#include "isakmp_ident.h"
#include "isakmp_inf.h"
#include "vendorid.h"
#include "gcmalloc.h"
#include "gssapi.h"
static void
gssapi_error(OM_uint32 status_code, const char *where,
const char *fmt, ...)
{
OM_uint32 message_context, maj_stat, min_stat;
gss_buffer_desc status_string;
va_list ap;
va_start(ap, fmt);
plogv(LLV_ERROR, where, NULL, fmt, ap);
va_end(ap);
message_context = 0;
do {
maj_stat = gss_display_status(&min_stat, status_code,
GSS_C_MECH_CODE, GSS_C_NO_OID, &message_context,
&status_string);
if (GSS_ERROR(maj_stat))
plog(LLV_ERROR, LOCATION, NULL,
"UNABLE TO GET GSSAPI ERROR CODE\n");
else {
plog(LLV_ERROR, where, NULL,
"%s\n", (char *)status_string.value);
gss_release_buffer(&min_stat, &status_string);
}
} while (message_context != 0);
}
/*
* vmbufs and gss_buffer_descs are really just the same on NetBSD, but
* this is to be portable.
*/
static int
gssapi_vm2gssbuf(vchar_t *vmbuf, gss_buffer_t gsstoken)
{
gsstoken->value = racoon_malloc(vmbuf->l);
if (gsstoken->value == NULL)
return -1;
memcpy(gsstoken->value, vmbuf->v, vmbuf->l);
gsstoken->length = vmbuf->l;
return 0;
}
static int
gssapi_gss2vmbuf(gss_buffer_t gsstoken, vchar_t **vmbuf)
{
*vmbuf = vmalloc(gsstoken->length);
if (*vmbuf == NULL)
return -1;
memcpy((*vmbuf)->v, gsstoken->value, gsstoken->length);
(*vmbuf)->l = gsstoken->length;
return 0;
}
vchar_t *
gssapi_get_default_gss_id(void)
{
char name[NI_MAXHOST];
vchar_t *gssid;
if (gethostname(name, sizeof(name)) != 0) {
plog(LLV_ERROR, LOCATION, NULL, "gethostname failed: %s\n",
strerror(errno));
return (NULL);
}
name[sizeof(name) - 1] = '\0';
gssid = racoon_malloc(sizeof(*gssid));
gssid->l = asprintf(&gssid->v, "%s/%s", GSSAPI_DEF_NAME, name);
return (gssid);
}
static int
gssapi_get_default_name(struct ph1handle *iph1, int remote, gss_name_t *service)
{
char name[NI_MAXHOST];
struct sockaddr *sa;
gss_buffer_desc name_token;
OM_uint32 min_stat, maj_stat;
sa = remote ? iph1->remote : iph1->local;
if (getnameinfo(sa, sysdep_sa_len(sa), name, NI_MAXHOST, NULL, 0, 0) != 0)
return -1;
name_token.length = asprintf((char **)&name_token.value,
"%s@%s", GSSAPI_DEF_NAME, name);
maj_stat = gss_import_name(&min_stat, &name_token,
GSS_C_NT_HOSTBASED_SERVICE, service);
if (GSS_ERROR(maj_stat)) {
gssapi_error(min_stat, LOCATION, "import name\n");
maj_stat = gss_release_buffer(&min_stat, &name_token);
if (GSS_ERROR(maj_stat))
gssapi_error(min_stat, LOCATION, "release name_token");
return -1;
}
maj_stat = gss_release_buffer(&min_stat, &name_token);
if (GSS_ERROR(maj_stat))
gssapi_error(min_stat, LOCATION, "release name_token");
return 0;
}
static int
gssapi_init(struct ph1handle *iph1)
{
struct gssapi_ph1_state *gps;
gss_buffer_desc id_token, cred_token;
gss_buffer_t cred = &cred_token;
gss_name_t princ, canon_princ;
OM_uint32 maj_stat, min_stat;
gps = racoon_calloc(1, sizeof (struct gssapi_ph1_state));
if (gps == NULL) {
plog(LLV_ERROR, LOCATION, NULL, "racoon_calloc failed\n");
return -1;
}
gps->gss_context = GSS_C_NO_CONTEXT;
gps->gss_cred = GSS_C_NO_CREDENTIAL;
gssapi_set_state(iph1, gps);
if (iph1->rmconf->proposal->gssid != NULL) {
id_token.length = iph1->rmconf->proposal->gssid->l;
id_token.value = iph1->rmconf->proposal->gssid->v;
maj_stat = gss_import_name(&min_stat, &id_token, GSS_C_NO_OID,
&princ);
if (GSS_ERROR(maj_stat)) {
gssapi_error(min_stat, LOCATION, "import name\n");
gssapi_free_state(iph1);
return -1;
}
} else
gssapi_get_default_name(iph1, 0, &princ);
maj_stat = gss_canonicalize_name(&min_stat, princ, GSS_C_NO_OID,
&canon_princ);
if (GSS_ERROR(maj_stat)) {
gssapi_error(min_stat, LOCATION, "canonicalize name\n");
maj_stat = gss_release_name(&min_stat, &princ);
if (GSS_ERROR(maj_stat))
gssapi_error(min_stat, LOCATION, "release princ\n");
gssapi_free_state(iph1);
return -1;
}
maj_stat = gss_release_name(&min_stat, &princ);
if (GSS_ERROR(maj_stat))
gssapi_error(min_stat, LOCATION, "release princ\n");
maj_stat = gss_export_name(&min_stat, canon_princ, cred);
if (GSS_ERROR(maj_stat)) {
gssapi_error(min_stat, LOCATION, "export name\n");
maj_stat = gss_release_name(&min_stat, &canon_princ);
if (GSS_ERROR(maj_stat))
gssapi_error(min_stat, LOCATION,
"release canon_princ\n");
gssapi_free_state(iph1);
return -1;
}
#if 0
/*
* XXXJRT Did this debug message ever work? This is a GSS name
* blob at this point.
*/
plog(LLV_DEBUG, LOCATION, NULL, "will try to acquire '%.*s' creds\n",
cred->length, cred->value);
#endif
maj_stat = gss_release_buffer(&min_stat, cred);
if (GSS_ERROR(maj_stat))
gssapi_error(min_stat, LOCATION, "release cred buffer\n");
maj_stat = gss_acquire_cred(&min_stat, canon_princ, GSS_C_INDEFINITE,
GSS_C_NO_OID_SET, GSS_C_BOTH, &gps->gss_cred, NULL, NULL);
if (GSS_ERROR(maj_stat)) {
gssapi_error(min_stat, LOCATION, "acquire cred\n");
maj_stat = gss_release_name(&min_stat, &canon_princ);
if (GSS_ERROR(maj_stat))
gssapi_error(min_stat, LOCATION,
"release canon_princ\n");
gssapi_free_state(iph1);
return -1;
}
maj_stat = gss_release_name(&min_stat, &canon_princ);
if (GSS_ERROR(maj_stat))
gssapi_error(min_stat, LOCATION, "release canon_princ\n");
return 0;
}
int
gssapi_get_itoken(struct ph1handle *iph1, int *lenp)
{
struct gssapi_ph1_state *gps;
gss_buffer_desc empty, name_token;
gss_buffer_t itoken, rtoken, dummy;
OM_uint32 maj_stat, min_stat;
gss_name_t partner;
if (gssapi_get_state(iph1) == NULL && gssapi_init(iph1) < 0)
return -1;
gps = gssapi_get_state(iph1);
empty.length = 0;
empty.value = NULL;
dummy = &empty;
if (iph1->approval != NULL && iph1->approval->gssid != NULL) {
plog(LLV_DEBUG, LOCATION, NULL,
"using provided service '%.*s'\n",
iph1->approval->gssid->l, iph1->approval->gssid->v);
name_token.length = iph1->approval->gssid->l;
name_token.value = iph1->approval->gssid->v;
maj_stat = gss_import_name(&min_stat, &name_token,
GSS_C_NO_OID, &partner);
if (GSS_ERROR(maj_stat)) {
gssapi_error(min_stat, LOCATION, "import of %.*s\n",
name_token.length, name_token.value);
return -1;
}
} else
if (gssapi_get_default_name(iph1, 1, &partner) < 0)
return -1;
rtoken = gps->gsscnt_p == 0 ? dummy : &gps->gss_p[gps->gsscnt_p - 1];
itoken = &gps->gss[gps->gsscnt];
gps->gss_status = gss_init_sec_context(&min_stat, gps->gss_cred,
&gps->gss_context, partner, GSS_C_NO_OID,
GSS_C_MUTUAL_FLAG | GSS_C_SEQUENCE_FLAG |
GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG,
0, GSS_C_NO_CHANNEL_BINDINGS, rtoken, NULL,
itoken, NULL, NULL);
if (GSS_ERROR(gps->gss_status)) {
gssapi_error(min_stat, LOCATION, "init_sec_context\n");
maj_stat = gss_release_name(&min_stat, &partner);
if (GSS_ERROR(maj_stat))
gssapi_error(min_stat, LOCATION, "release name\n");
return -1;
}
maj_stat = gss_release_name(&min_stat, &partner);
if (GSS_ERROR(maj_stat))
gssapi_error(min_stat, LOCATION, "release name\n");
plog(LLV_DEBUG, LOCATION, NULL, "gss_init_sec_context status %x\n",
gps->gss_status);
if (lenp)
*lenp = itoken->length;
if (itoken->length != 0)
gps->gsscnt++;
return 0;
}
/*
* Call gss_accept_context, with token just read from the wire.
*/
int
gssapi_get_rtoken(struct ph1handle *iph1, int *lenp)
{
struct gssapi_ph1_state *gps;
gss_buffer_desc name_token;
gss_buffer_t itoken, rtoken;
OM_uint32 min_stat, maj_stat;
gss_name_t client_name;
if (gssapi_get_state(iph1) == NULL && gssapi_init(iph1) < 0)
return -1;
gps = gssapi_get_state(iph1);
rtoken = &gps->gss_p[gps->gsscnt_p - 1];
itoken = &gps->gss[gps->gsscnt];
gps->gss_status = gss_accept_sec_context(&min_stat, &gps->gss_context,
gps->gss_cred, rtoken, GSS_C_NO_CHANNEL_BINDINGS, &client_name,
NULL, itoken, NULL, NULL, NULL);
if (GSS_ERROR(gps->gss_status)) {
gssapi_error(min_stat, LOCATION, "accept_sec_context\n");
return -1;
}
maj_stat = gss_display_name(&min_stat, client_name, &name_token, NULL);
if (GSS_ERROR(maj_stat)) {
gssapi_error(min_stat, LOCATION, "gss_display_name\n");
maj_stat = gss_release_name(&min_stat, &client_name);
if (GSS_ERROR(maj_stat))
gssapi_error(min_stat, LOCATION,
"release client_name\n");
return -1;
}
maj_stat = gss_release_name(&min_stat, &client_name);
if (GSS_ERROR(maj_stat))
gssapi_error(min_stat, LOCATION, "release client_name\n");
plog(LLV_DEBUG, LOCATION, NULL,
"gss_accept_sec_context: other side is %s\n",
(char *)name_token.value);
maj_stat = gss_release_buffer(&min_stat, &name_token);
if (GSS_ERROR(maj_stat))
gssapi_error(min_stat, LOCATION, "release name buffer\n");
if (itoken->length != 0)
gps->gsscnt++;
if (lenp)
*lenp = itoken->length;
return 0;
}
int
gssapi_save_received_token(struct ph1handle *iph1, vchar_t *token)
{
struct gssapi_ph1_state *gps;
gss_buffer_t gsstoken;
int ret;
if (gssapi_get_state(iph1) == NULL && gssapi_init(iph1) < 0)
return -1;
gps = gssapi_get_state(iph1);
gsstoken = &gps->gss_p[gps->gsscnt_p];
ret = gssapi_vm2gssbuf(token, gsstoken);
if (ret < 0)
return ret;
gps->gsscnt_p++;
return 0;
}
int
gssapi_get_token_to_send(struct ph1handle *iph1, vchar_t **token)
{
struct gssapi_ph1_state *gps;
gss_buffer_t gsstoken;
int ret;
gps = gssapi_get_state(iph1);
if (gps == NULL) {
plog(LLV_ERROR, LOCATION, NULL,
"gssapi not yet initialized?\n");
return -1;
}
gsstoken = &gps->gss[gps->gsscnt - 1];
ret = gssapi_gss2vmbuf(gsstoken, token);
if (ret < 0)
return ret;
return 0;
}
int
gssapi_get_itokens(struct ph1handle *iph1, vchar_t **tokens)
{
struct gssapi_ph1_state *gps;
int len, i;
vchar_t *toks;
char *p;
gps = gssapi_get_state(iph1);
if (gps == NULL) {
plog(LLV_ERROR, LOCATION, NULL,
"gssapi not yet initialized?\n");
return -1;
}
for (i = len = 0; i < gps->gsscnt; i++)
len += gps->gss[i].length;
toks = vmalloc(len);
if (toks == 0)
return -1;
p = (char *)toks->v;
for (i = 0; i < gps->gsscnt; i++) {
memcpy(p, gps->gss[i].value, gps->gss[i].length);
p += gps->gss[i].length;
}
*tokens = toks;
plog(LLV_DEBUG, LOCATION, NULL,
"%d itokens of length %d\n", gps->gsscnt, (*tokens)->l);
return 0;
}
int
gssapi_get_rtokens(struct ph1handle *iph1, vchar_t **tokens)
{
struct gssapi_ph1_state *gps;
int len, i;
vchar_t *toks;
char *p;
gps = gssapi_get_state(iph1);
if (gps == NULL) {
plog(LLV_ERROR, LOCATION, NULL,
"gssapi not yet initialized?\n");
return -1;
}
if (gssapi_more_tokens(iph1)) {
plog(LLV_ERROR, LOCATION, NULL,
"gssapi roundtrips not complete\n");
return -1;
}
for (i = len = 0; i < gps->gsscnt_p; i++)
len += gps->gss_p[i].length;
toks = vmalloc(len);
if (toks == 0)
return -1;
p = (char *)toks->v;
for (i = 0; i < gps->gsscnt_p; i++) {
memcpy(p, gps->gss_p[i].value, gps->gss_p[i].length);
p += gps->gss_p[i].length;
}
*tokens = toks;
return 0;
}
vchar_t *
gssapi_wraphash(struct ph1handle *iph1)
{
struct gssapi_ph1_state *gps;
OM_uint32 maj_stat, min_stat;
gss_buffer_desc hash_in_buf, hash_out_buf;
gss_buffer_t hash_in = &hash_in_buf, hash_out = &hash_out_buf;
vchar_t *outbuf;
gps = gssapi_get_state(iph1);
if (gps == NULL) {
plog(LLV_ERROR, LOCATION, NULL,
"gssapi not yet initialized?\n");
return NULL;
}
if (gssapi_more_tokens(iph1)) {
plog(LLV_ERROR, LOCATION, NULL,
"gssapi roundtrips not complete\n");
return NULL;
}
if (gssapi_vm2gssbuf(iph1->hash, hash_in) < 0) {
plog(LLV_ERROR, LOCATION, NULL, "vm2gssbuf failed\n");
return NULL;
}
maj_stat = gss_wrap(&min_stat, gps->gss_context, 1, GSS_C_QOP_DEFAULT,
hash_in, NULL, hash_out);
if (GSS_ERROR(maj_stat)) {
gssapi_error(min_stat, LOCATION, "wrapping hash value\n");
maj_stat = gss_release_buffer(&min_stat, hash_in);
if (GSS_ERROR(maj_stat))
gssapi_error(min_stat, LOCATION,
"release hash_in buffer\n");
return NULL;
}
plog(LLV_DEBUG, LOCATION, NULL, "wrapped HASH, ilen %d olen %d\n",
hash_in->length, hash_out->length);
maj_stat = gss_release_buffer(&min_stat, hash_in);
if (GSS_ERROR(maj_stat))
gssapi_error(min_stat, LOCATION, "release hash_in buffer\n");
if (gssapi_gss2vmbuf(hash_out, &outbuf) < 0) {
plog(LLV_ERROR, LOCATION, NULL, "gss2vmbuf failed\n");
maj_stat = gss_release_buffer(&min_stat, hash_out);
if (GSS_ERROR(maj_stat))
gssapi_error(min_stat, LOCATION,
"release hash_out buffer\n");
return NULL;
}
maj_stat = gss_release_buffer(&min_stat, hash_out);
if (GSS_ERROR(maj_stat))
gssapi_error(min_stat, LOCATION, "release hash_out buffer\n");
return outbuf;
}
vchar_t *
gssapi_unwraphash(struct ph1handle *iph1)
{
struct gssapi_ph1_state *gps;
OM_uint32 maj_stat, min_stat;
gss_buffer_desc hashbuf, hash_outbuf;
gss_buffer_t hash_in = &hashbuf, hash_out = &hash_outbuf;
vchar_t *outbuf;
gps = gssapi_get_state(iph1);
if (gps == NULL) {
plog(LLV_ERROR, LOCATION, NULL,
"gssapi not yet initialized?\n");
return NULL;
}
hashbuf.length = ntohs(iph1->pl_hash->h.len) - sizeof(*iph1->pl_hash);
hashbuf.value = (char *)(iph1->pl_hash + 1);
plog(LLV_DEBUG, LOCATION, NULL, "unwrapping HASH of len %d\n",
hashbuf.length);
maj_stat = gss_unwrap(&min_stat, gps->gss_context, hash_in, hash_out,
NULL, NULL);
if (GSS_ERROR(maj_stat)) {
gssapi_error(min_stat, LOCATION, "unwrapping hash value\n");
return NULL;
}
if (gssapi_gss2vmbuf(hash_out, &outbuf) < 0) {
plog(LLV_ERROR, LOCATION, NULL, "gss2vmbuf failed\n");
maj_stat = gss_release_buffer(&min_stat, hash_out);
if (GSS_ERROR(maj_stat))
gssapi_error(min_stat, LOCATION,
"release hash_out buffer\n");
return NULL;
}
maj_stat = gss_release_buffer(&min_stat, hash_out);
if (GSS_ERROR(maj_stat))
gssapi_error(min_stat, LOCATION, "release hash_out buffer\n");
return outbuf;
}
void
gssapi_set_id_sent(struct ph1handle *iph1)
{
struct gssapi_ph1_state *gps;
gps = gssapi_get_state(iph1);
gps->gss_flags |= GSSFLAG_ID_SENT;
}
int
gssapi_id_sent(struct ph1handle *iph1)
{
struct gssapi_ph1_state *gps;
gps = gssapi_get_state(iph1);
return (gps->gss_flags & GSSFLAG_ID_SENT) != 0;
}
void
gssapi_set_id_rcvd(struct ph1handle *iph1)
{
struct gssapi_ph1_state *gps;
gps = gssapi_get_state(iph1);
gps->gss_flags |= GSSFLAG_ID_RCVD;
}
int
gssapi_id_rcvd(struct ph1handle *iph1)
{
struct gssapi_ph1_state *gps;
gps = gssapi_get_state(iph1);
return (gps->gss_flags & GSSFLAG_ID_RCVD) != 0;
}
void
gssapi_free_state(struct ph1handle *iph1)
{
struct gssapi_ph1_state *gps;
OM_uint32 maj_stat, min_stat;
gps = gssapi_get_state(iph1);
if (gps == NULL)
return;
gssapi_set_state(iph1, NULL);
if (gps->gss_cred != GSS_C_NO_CREDENTIAL) {
maj_stat = gss_release_cred(&min_stat, &gps->gss_cred);
if (GSS_ERROR(maj_stat))
gssapi_error(min_stat, LOCATION,
"releasing credentials\n");
}
racoon_free(gps);
}
vchar_t *
gssapi_get_id(struct ph1handle *iph1)
{
gss_buffer_desc id_buffer;
gss_buffer_t id = &id_buffer;
gss_name_t defname, canon_name;
OM_uint32 min_stat, maj_stat;
vchar_t *vmbuf;
if (iph1->rmconf->proposal->gssid != NULL)
return (vdup(iph1->rmconf->proposal->gssid));
if (gssapi_get_default_name(iph1, 0, &defname) < 0)
return NULL;
maj_stat = gss_canonicalize_name(&min_stat, defname, GSS_C_NO_OID,
&canon_name);
if (GSS_ERROR(maj_stat)) {
gssapi_error(min_stat, LOCATION, "canonicalize name\n");
maj_stat = gss_release_name(&min_stat, &defname);
if (GSS_ERROR(maj_stat))
gssapi_error(min_stat, LOCATION,
"release default name\n");
return NULL;
}
maj_stat = gss_release_name(&min_stat, &defname);
if (GSS_ERROR(maj_stat))
gssapi_error(min_stat, LOCATION, "release default name\n");
maj_stat = gss_export_name(&min_stat, canon_name, id);
if (GSS_ERROR(maj_stat)) {
gssapi_error(min_stat, LOCATION, "export name\n");
maj_stat = gss_release_name(&min_stat, &canon_name);
if (GSS_ERROR(maj_stat))
gssapi_error(min_stat, LOCATION,
"release canonical name\n");
return NULL;
}
maj_stat = gss_release_name(&min_stat, &canon_name);
if (GSS_ERROR(maj_stat))
gssapi_error(min_stat, LOCATION, "release canonical name\n");
#if 0
/*
* XXXJRT Did this debug message ever work? This is a GSS name
* blob at this point.
*/
plog(LLV_DEBUG, LOCATION, NULL, "will try to acquire '%.*s' creds\n",
id->length, id->value);
#endif
if (gssapi_gss2vmbuf(id, &vmbuf) < 0) {
plog(LLV_ERROR, LOCATION, NULL, "gss2vmbuf failed\n");
maj_stat = gss_release_buffer(&min_stat, id);
if (GSS_ERROR(maj_stat))
gssapi_error(min_stat, LOCATION, "release id buffer\n");
return NULL;
}
maj_stat = gss_release_buffer(&min_stat, id);
if (GSS_ERROR(maj_stat))
gssapi_error(min_stat, LOCATION, "release id buffer\n");
return vmbuf;
}
#else
int __gssapi_dUmMy;
#endif

View File

@ -0,0 +1,89 @@
/* $Id: gssapi.h,v 1.1.1.1 2005/02/12 11:12:00 manu Exp $ */
/*
* Copyright 2000 Wasabi Systems, Inc.
* All rights reserved.
*
* This software was written by Frank van der Linden of Wasabi Systems
* for Zembu Labs, Inc. http://www.zembu.com/
*
* 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.
* 3. The name of Wasabi Systems, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
* 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.
*/
#ifdef __FreeBSD__
#include "/usr/include/gssapi.h"
#else
#include <gssapi/gssapi.h>
#endif
#define GSSAPI_DEF_NAME "host"
struct ph1handle;
struct isakmpsa;
struct gssapi_ph1_state {
int gsscnt; /* # of token we're working on */
int gsscnt_p; /* # of token we're working on */
gss_buffer_desc gss[3]; /* gss-api tokens. */
/* NOTE: XXX this restricts the max # */
/* to 3. More should never happen */
gss_buffer_desc gss_p[3];
gss_ctx_id_t gss_context; /* context for gss_init_sec_context */
OM_uint32 gss_status; /* retval from gss_init_sec_context */
gss_cred_id_t gss_cred; /* acquired credentials */
int gss_flags;
#define GSSFLAG_ID_SENT 0x0001
#define GSSFLAG_ID_RCVD 0x0001
};
#define gssapi_get_state(ph) \
((struct gssapi_ph1_state *)((ph)->gssapi_state))
#define gssapi_set_state(ph, st) \
(ph)->gssapi_state = (st)
#define gssapi_more_tokens(ph) \
((gssapi_get_state(ph)->gss_status & GSS_S_CONTINUE_NEEDED) != 0)
int gssapi_get_itoken __P((struct ph1handle *, int *));
int gssapi_get_rtoken __P((struct ph1handle *, int *));
int gssapi_save_received_token __P((struct ph1handle *, vchar_t *));
int gssapi_get_token_to_send __P((struct ph1handle *, vchar_t **));
int gssapi_get_itokens __P((struct ph1handle *, vchar_t **));
int gssapi_get_rtokens __P((struct ph1handle *, vchar_t **));
vchar_t *gssapi_wraphash __P((struct ph1handle *));
vchar_t *gssapi_unwraphash __P((struct ph1handle *));
void gssapi_set_id_sent __P((struct ph1handle *));
int gssapi_id_sent __P((struct ph1handle *));
void gssapi_set_id_rcvd __P((struct ph1handle *));
int gssapi_id_rcvd __P((struct ph1handle *));
void gssapi_free_state __P((struct ph1handle *));
vchar_t *gssapi_get_id __P((struct ph1handle *));
vchar_t *gssapi_get_default_gss_id __P((void));

View File

@ -0,0 +1,953 @@
/* $Id: handler.c,v 1.1.1.1 2005/02/12 11:12:00 manu Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#include "config.h"
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include "var.h"
#include "misc.h"
#include "vmbuf.h"
#include "plog.h"
#include "sockmisc.h"
#include "debug.h"
#include "schedule.h"
#include "grabmyaddr.h"
#include "algorithm.h"
#include "crypto_openssl.h"
#include "policy.h"
#include "proposal.h"
#include "isakmp_var.h"
#include "evt.h"
#include "isakmp.h"
#ifdef ENABLE_HYBRID
#include "isakmp_xauth.h"
#include "isakmp_cfg.h"
#endif
#include "isakmp_inf.h"
#include "oakley.h"
#include "remoteconf.h"
#include "localconf.h"
#include "handler.h"
#include "gcmalloc.h"
#include "nattraversal.h"
#ifdef HAVE_GSSAPI
#include "gssapi.h"
#endif
static LIST_HEAD(_ph1tree_, ph1handle) ph1tree;
static LIST_HEAD(_ph2tree_, ph2handle) ph2tree;
static LIST_HEAD(_ctdtree_, contacted) ctdtree;
static LIST_HEAD(_rcptree_, recvdpkt) rcptree;
static void del_recvdpkt __P((struct recvdpkt *));
static void rem_recvdpkt __P((struct recvdpkt *));
static void sweep_recvdpkt __P((void *));
/*
* functions about management of the isakmp status table
*/
/* %%% management phase 1 handler */
/*
* search for isakmpsa handler with isakmp index.
*/
extern caddr_t val2str(const char *, size_t);
struct ph1handle *
getph1byindex(index)
isakmp_index *index;
{
struct ph1handle *p;
LIST_FOREACH(p, &ph1tree, chain) {
if (p->status == PHASE1ST_EXPIRED)
continue;
if (memcmp(&p->index, index, sizeof(*index)) == 0)
return p;
}
return NULL;
}
/*
* search for isakmp handler by i_ck in index.
*/
struct ph1handle *
getph1byindex0(index)
isakmp_index *index;
{
struct ph1handle *p;
LIST_FOREACH(p, &ph1tree, chain) {
if (p->status == PHASE1ST_EXPIRED)
continue;
if (memcmp(&p->index, index, sizeof(cookie_t)) == 0)
return p;
}
return NULL;
}
/*
* search for isakmpsa handler by source and remote address.
* don't use port number to search because this function search
* with phase 2's destinaion.
*/
struct ph1handle *
getph1byaddr(local, remote)
struct sockaddr *local, *remote;
{
struct ph1handle *p;
LIST_FOREACH(p, &ph1tree, chain) {
if (p->status == PHASE1ST_EXPIRED)
continue;
if (cmpsaddrwop(local, p->local) == 0
&& cmpsaddrwop(remote, p->remote) == 0)
return p;
}
return NULL;
}
/*
* search for isakmpsa handler by remote address.
* don't use port number to search because this function search
* with phase 2's destinaion.
*/
struct ph1handle *
getph1bydstaddr(remote)
struct sockaddr *remote;
{
struct ph1handle *p;
LIST_FOREACH(p, &ph1tree, chain) {
if (p->status == PHASE1ST_EXPIRED)
continue;
if (cmpsaddrwop(remote, p->remote) == 0)
return p;
}
return NULL;
}
/*
* dump isakmp-sa
*/
vchar_t *
dumpph1()
{
struct ph1handle *iph1;
struct ph1dump *pd;
int cnt = 0;
vchar_t *buf;
/* get length of buffer */
LIST_FOREACH(iph1, &ph1tree, chain)
cnt++;
buf = vmalloc(cnt * sizeof(struct ph1dump));
if (buf == NULL) {
plog(LLV_ERROR, LOCATION, NULL,
"failed to get buffer\n");
return NULL;
}
pd = (struct ph1dump *)buf->v;
LIST_FOREACH(iph1, &ph1tree, chain) {
memcpy(&pd->index, &iph1->index, sizeof(iph1->index));
pd->status = iph1->status;
pd->side = iph1->side;
memcpy(&pd->remote, iph1->remote, sysdep_sa_len(iph1->remote));
memcpy(&pd->local, iph1->local, sysdep_sa_len(iph1->local));
pd->version = iph1->version;
pd->etype = iph1->etype;
pd->created = iph1->created;
pd->ph2cnt = iph1->ph2cnt;
pd++;
}
return buf;
}
/*
* create new isakmp Phase 1 status record to handle isakmp in Phase1
*/
struct ph1handle *
newph1()
{
struct ph1handle *iph1;
/* create new iph1 */
iph1 = racoon_calloc(1, sizeof(*iph1));
if (iph1 == NULL)
return NULL;
iph1->status = PHASE1ST_SPAWN;
#ifdef ENABLE_DPD
iph1->dpd_support = 0;
iph1->dpd_lastack = 0;
iph1->dpd_seq = 0;
iph1->dpd_fails = 0;
iph1->dpd_r_u = NULL;
#endif
return iph1;
}
/*
* delete new isakmp Phase 1 status record to handle isakmp in Phase1
*/
void
delph1(iph1)
struct ph1handle *iph1;
{
/* SA down shell script hook */
if (iph1 != NULL)
script_hook(iph1, SCRIPT_PHASE1_DOWN);
EVT_PUSH(iph1->local, iph1->remote, EVTT_PHASE1_DOWN, NULL);
#ifdef ENABLE_NATT
if (iph1->natt_flags & NAT_KA_QUEUED)
natt_keepalive_remove (iph1->local, iph1->remote);
if (iph1->natt_options) {
racoon_free(iph1->natt_options);
iph1->natt_options = NULL;
}
#endif
if (iph1->remote) {
racoon_free(iph1->remote);
iph1->remote = NULL;
}
if (iph1->local) {
racoon_free(iph1->local);
iph1->local = NULL;
}
#ifdef ENABLE_HYBRID
if (iph1->mode_cfg)
isakmp_cfg_rmstate(iph1);
#endif
VPTRINIT(iph1->authstr);
sched_scrub_param(iph1);
iph1->sce = NULL;
iph1->scr = NULL;
VPTRINIT(iph1->sendbuf);
VPTRINIT(iph1->dhpriv);
VPTRINIT(iph1->dhpub);
VPTRINIT(iph1->dhpub_p);
VPTRINIT(iph1->dhgxy);
VPTRINIT(iph1->nonce);
VPTRINIT(iph1->nonce_p);
VPTRINIT(iph1->skeyid);
VPTRINIT(iph1->skeyid_d);
VPTRINIT(iph1->skeyid_a);
VPTRINIT(iph1->skeyid_e);
VPTRINIT(iph1->key);
VPTRINIT(iph1->hash);
VPTRINIT(iph1->sig);
VPTRINIT(iph1->sig_p);
oakley_delcert(iph1->cert);
iph1->cert = NULL;
oakley_delcert(iph1->cert_p);
iph1->cert_p = NULL;
oakley_delcert(iph1->crl_p);
iph1->crl_p = NULL;
oakley_delcert(iph1->cr_p);
iph1->cr_p = NULL;
VPTRINIT(iph1->id);
VPTRINIT(iph1->id_p);
if (iph1->ivm) {
oakley_delivm(iph1->ivm);
iph1->ivm = NULL;
}
VPTRINIT(iph1->sa);
VPTRINIT(iph1->sa_ret);
#ifdef HAVE_GSSAPI
VPTRINIT(iph1->gi_i);
VPTRINIT(iph1->gi_r);
gssapi_free_state(iph1);
#endif
racoon_free(iph1);
}
/*
* create new isakmp Phase 1 status record to handle isakmp in Phase1
*/
int
insph1(iph1)
struct ph1handle *iph1;
{
/* validity check */
if (iph1->remote == NULL) {
plog(LLV_ERROR, LOCATION, NULL,
"invalid isakmp SA handler. no remote address.\n");
return -1;
}
LIST_INSERT_HEAD(&ph1tree, iph1, chain);
return 0;
}
void
remph1(iph1)
struct ph1handle *iph1;
{
LIST_REMOVE(iph1, chain);
}
/*
* flush isakmp-sa
*/
void
flushph1()
{
struct ph1handle *p, *next;
for (p = LIST_FIRST(&ph1tree); p; p = next) {
next = LIST_NEXT(p, chain);
/* send delete information */
if (p->status == PHASE1ST_ESTABLISHED)
isakmp_info_send_d1(p);
remph1(p);
delph1(p);
}
}
void
initph1tree()
{
LIST_INIT(&ph1tree);
}
/* %%% management phase 2 handler */
/*
* search ph2handle with policy id.
*/
struct ph2handle *
getph2byspid(spid)
u_int32_t spid;
{
struct ph2handle *p;
LIST_FOREACH(p, &ph2tree, chain) {
/*
* there are ph2handle independent on policy
* such like informational exchange.
*/
if (p->spid == spid)
return p;
}
return NULL;
}
/*
* search ph2handle with sequence number.
*/
struct ph2handle *
getph2byseq(seq)
u_int32_t seq;
{
struct ph2handle *p;
LIST_FOREACH(p, &ph2tree, chain) {
if (p->seq == seq)
return p;
}
return NULL;
}
/*
* search ph2handle with message id.
*/
struct ph2handle *
getph2bymsgid(iph1, msgid)
struct ph1handle *iph1;
u_int32_t msgid;
{
struct ph2handle *p;
LIST_FOREACH(p, &ph2tree, chain) {
if (p->msgid == msgid)
return p;
}
return NULL;
}
/*
* call by pk_recvexpire().
*/
struct ph2handle *
getph2bysaidx(src, dst, proto_id, spi)
struct sockaddr *src, *dst;
u_int proto_id;
u_int32_t spi;
{
struct ph2handle *iph2;
struct saproto *pr;
LIST_FOREACH(iph2, &ph2tree, chain) {
if (iph2->proposal == NULL && iph2->approval == NULL)
continue;
if (iph2->approval != NULL) {
for (pr = iph2->approval->head; pr != NULL;
pr = pr->next) {
if (proto_id != pr->proto_id)
break;
if (spi == pr->spi || spi == pr->spi_p)
return iph2;
}
} else if (iph2->proposal != NULL) {
for (pr = iph2->proposal->head; pr != NULL;
pr = pr->next) {
if (proto_id != pr->proto_id)
break;
if (spi == pr->spi)
return iph2;
}
}
}
return NULL;
}
/*
* create new isakmp Phase 2 status record to handle isakmp in Phase2
*/
struct ph2handle *
newph2()
{
struct ph2handle *iph2 = NULL;
/* create new iph2 */
iph2 = racoon_calloc(1, sizeof(*iph2));
if (iph2 == NULL)
return NULL;
iph2->status = PHASE1ST_SPAWN;
return iph2;
}
/*
* initialize ph2handle
* NOTE: don't initialize src/dst.
* SPI in the proposal is cleared.
*/
void
initph2(iph2)
struct ph2handle *iph2;
{
sched_scrub_param(iph2);
iph2->sce = NULL;
iph2->scr = NULL;
VPTRINIT(iph2->sendbuf);
VPTRINIT(iph2->msg1);
/* clear spi, keep variables in the proposal */
if (iph2->proposal) {
struct saproto *pr;
for (pr = iph2->proposal->head; pr != NULL; pr = pr->next)
pr->spi = 0;
}
/* clear approval */
if (iph2->approval) {
flushsaprop(iph2->approval);
iph2->approval = NULL;
}
/* clear the generated policy */
if (iph2->spidx_gen) {
delsp_bothdir((struct policyindex *)iph2->spidx_gen);
racoon_free(iph2->spidx_gen);
iph2->spidx_gen = NULL;
}
if (iph2->pfsgrp) {
oakley_dhgrp_free(iph2->pfsgrp);
iph2->pfsgrp = NULL;
}
VPTRINIT(iph2->dhpriv);
VPTRINIT(iph2->dhpub);
VPTRINIT(iph2->dhpub_p);
VPTRINIT(iph2->dhgxy);
VPTRINIT(iph2->id);
VPTRINIT(iph2->id_p);
VPTRINIT(iph2->nonce);
VPTRINIT(iph2->nonce_p);
VPTRINIT(iph2->sa);
VPTRINIT(iph2->sa_ret);
if (iph2->ivm) {
oakley_delivm(iph2->ivm);
iph2->ivm = NULL;
}
}
/*
* delete new isakmp Phase 2 status record to handle isakmp in Phase2
*/
void
delph2(iph2)
struct ph2handle *iph2;
{
initph2(iph2);
if (iph2->src) {
racoon_free(iph2->src);
iph2->src = NULL;
}
if (iph2->dst) {
racoon_free(iph2->dst);
iph2->dst = NULL;
}
if (iph2->src_id) {
racoon_free(iph2->src_id);
iph2->src_id = NULL;
}
if (iph2->dst_id) {
racoon_free(iph2->dst_id);
iph2->dst_id = NULL;
}
if (iph2->proposal) {
flushsaprop(iph2->proposal);
iph2->proposal = NULL;
}
racoon_free(iph2);
}
/*
* create new isakmp Phase 2 status record to handle isakmp in Phase2
*/
int
insph2(iph2)
struct ph2handle *iph2;
{
LIST_INSERT_HEAD(&ph2tree, iph2, chain);
return 0;
}
void
remph2(iph2)
struct ph2handle *iph2;
{
LIST_REMOVE(iph2, chain);
}
void
initph2tree()
{
LIST_INIT(&ph2tree);
}
void
flushph2()
{
struct ph2handle *p, *next;
for (p = LIST_FIRST(&ph2tree); p; p = next) {
next = LIST_NEXT(p, chain);
/* send delete information */
if (p->status == PHASE2ST_ESTABLISHED)
isakmp_info_send_d2(p);
unbindph12(p);
remph2(p);
delph2(p);
}
}
/*
* Delete all Phase 2 handlers for this src/dst/proto. This
* is used during INITIAL-CONTACT processing (so no need to
* send a message to the peer).
*/
void
deleteallph2(src, dst, proto_id)
struct sockaddr *src, *dst;
u_int proto_id;
{
struct ph2handle *iph2, *next;
struct saproto *pr;
for (iph2 = LIST_FIRST(&ph2tree); iph2 != NULL; iph2 = next) {
next = LIST_NEXT(iph2, chain);
if (iph2->proposal == NULL && iph2->approval == NULL)
continue;
if (iph2->approval != NULL) {
for (pr = iph2->approval->head; pr != NULL;
pr = pr->next) {
if (proto_id == pr->proto_id)
goto zap_it;
}
} else if (iph2->proposal != NULL) {
for (pr = iph2->proposal->head; pr != NULL;
pr = pr->next) {
if (proto_id == pr->proto_id)
goto zap_it;
}
}
continue;
zap_it:
unbindph12(iph2);
remph2(iph2);
delph2(iph2);
}
}
/* %%% */
void
bindph12(iph1, iph2)
struct ph1handle *iph1;
struct ph2handle *iph2;
{
iph2->ph1 = iph1;
LIST_INSERT_HEAD(&iph1->ph2tree, iph2, ph1bind);
}
void
unbindph12(iph2)
struct ph2handle *iph2;
{
if (iph2->ph1 != NULL) {
iph2->ph1 = NULL;
LIST_REMOVE(iph2, ph1bind);
}
}
/* %%% management contacted list */
/*
* search contacted list.
*/
struct contacted *
getcontacted(remote)
struct sockaddr *remote;
{
struct contacted *p;
LIST_FOREACH(p, &ctdtree, chain) {
if (cmpsaddrstrict(remote, p->remote) == 0)
return p;
}
return NULL;
}
/*
* create new isakmp Phase 2 status record to handle isakmp in Phase2
*/
int
inscontacted(remote)
struct sockaddr *remote;
{
struct contacted *new;
/* create new iph2 */
new = racoon_calloc(1, sizeof(*new));
if (new == NULL)
return -1;
new->remote = dupsaddr(remote);
LIST_INSERT_HEAD(&ctdtree, new, chain);
return 0;
}
void
initctdtree()
{
LIST_INIT(&ctdtree);
}
/*
* check the response has been sent to the peer. when not, simply reply
* the buffered packet to the peer.
* OUT:
* 0: the packet is received at the first time.
* 1: the packet was processed before.
* 2: the packet was processed before, but the address mismatches.
* -1: error happened.
*/
int
check_recvdpkt(remote, local, rbuf)
struct sockaddr *remote, *local;
vchar_t *rbuf;
{
vchar_t *hash;
struct recvdpkt *r;
time_t t;
int len, s;
/* set current time */
t = time(NULL);
hash = eay_md5_one(rbuf);
if (!hash) {
plog(LLV_ERROR, LOCATION, NULL,
"failed to allocate buffer.\n");
return -1;
}
LIST_FOREACH(r, &rcptree, chain) {
if (memcmp(hash->v, r->hash->v, r->hash->l) == 0)
break;
}
vfree(hash);
/* this is the first time to receive the packet */
if (r == NULL)
return 0;
/*
* the packet was processed before, but the remote address mismatches.
*/
if (cmpsaddrstrict(remote, r->remote) != 0)
return 2;
/*
* it should not check the local address because the packet
* may arrive at other interface.
*/
/* check the previous time to send */
if (t - r->time_send < 1) {
plog(LLV_WARNING, LOCATION, NULL,
"the packet retransmitted in a short time from %s\n",
saddr2str(remote));
/*XXX should it be error ? */
}
/* select the socket to be sent */
s = getsockmyaddr(r->local);
if (s == -1)
return -1;
/* resend the packet if needed */
len = sendfromto(s, r->sendbuf->v, r->sendbuf->l,
r->local, r->remote, lcconf->count_persend);
if (len == -1) {
plog(LLV_ERROR, LOCATION, NULL, "sendfromto failed\n");
return -1;
}
/* check the retry counter */
r->retry_counter--;
if (r->retry_counter <= 0) {
rem_recvdpkt(r);
del_recvdpkt(r);
plog(LLV_DEBUG, LOCATION, NULL,
"deleted the retransmission packet to %s.\n",
saddr2str(remote));
} else
r->time_send = t;
return 1;
}
/*
* adding a hash of received packet into the received list.
*/
int
add_recvdpkt(remote, local, sbuf, rbuf)
struct sockaddr *remote, *local;
vchar_t *sbuf, *rbuf;
{
struct recvdpkt *new = NULL;
if (lcconf->retry_counter == 0) {
/* no need to add it */
return 0;
}
new = racoon_calloc(1, sizeof(*new));
if (!new) {
plog(LLV_ERROR, LOCATION, NULL,
"failed to allocate buffer.\n");
return -1;
}
new->hash = eay_md5_one(rbuf);
if (!new->hash) {
plog(LLV_ERROR, LOCATION, NULL,
"failed to allocate buffer.\n");
del_recvdpkt(new);
return -1;
}
new->remote = dupsaddr(remote);
if (new->remote == NULL) {
plog(LLV_ERROR, LOCATION, NULL,
"failed to allocate buffer.\n");
del_recvdpkt(new);
return -1;
}
new->local = dupsaddr(local);
if (new->local == NULL) {
plog(LLV_ERROR, LOCATION, NULL,
"failed to allocate buffer.\n");
del_recvdpkt(new);
return -1;
}
new->sendbuf = vdup(sbuf);
if (new->sendbuf == NULL) {
plog(LLV_ERROR, LOCATION, NULL,
"failed to allocate buffer.\n");
del_recvdpkt(new);
return -1;
}
new->retry_counter = lcconf->retry_counter;
new->time_send = 0;
new->created = time(NULL);
LIST_INSERT_HEAD(&rcptree, new, chain);
return 0;
}
void
del_recvdpkt(r)
struct recvdpkt *r;
{
if (r->remote)
racoon_free(r->remote);
if (r->local)
racoon_free(r->local);
if (r->hash)
vfree(r->hash);
if (r->sendbuf)
vfree(r->sendbuf);
racoon_free(r);
}
void
rem_recvdpkt(r)
struct recvdpkt *r;
{
LIST_REMOVE(r, chain);
}
void
sweep_recvdpkt(dummy)
void *dummy;
{
struct recvdpkt *r, *next;
time_t t, lt;
/* set current time */
t = time(NULL);
/* set the lifetime of the retransmission */
lt = lcconf->retry_counter * lcconf->retry_interval;
for (r = LIST_FIRST(&rcptree); r; r = next) {
next = LIST_NEXT(r, chain);
if (t - r->created > lt) {
rem_recvdpkt(r);
del_recvdpkt(r);
}
}
sched_new(lt, sweep_recvdpkt, NULL);
}
void
init_recvdpkt()
{
time_t lt = lcconf->retry_counter * lcconf->retry_interval;
LIST_INIT(&rcptree);
sched_new(lt, sweep_recvdpkt, NULL);
}
#ifdef ENABLE_HYBRID
/*
* Retruns 0 if the address was obtained by ISAKMP mode config, 1 otherwise
* This should be in isakmp_cfg.c but ph1tree being private, it must be there
*/
int
exclude_cfg_addr(addr)
const struct sockaddr *addr;
{
struct ph1handle *p;
struct sockaddr_in *sin;
LIST_FOREACH(p, &ph1tree, chain) {
if ((p->mode_cfg != NULL) &&
(p->mode_cfg->flags & ISAKMP_CFG_GOT_ADDR4) &&
(addr->sa_family == AF_INET)) {
sin = (struct sockaddr_in *)addr;
if (sin->sin_addr.s_addr == p->mode_cfg->addr4.s_addr)
return 0;
}
}
return 1;
}
#endif

View File

@ -0,0 +1,463 @@
/* $Id: handler.h,v 1.1.1.1 2005/02/12 11:12:01 manu Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#ifndef _HANDLER_H
#define _HANDLER_H
#include <sys/queue.h>
#include <openssl/rsa.h>
#include <sys/time.h>
#include "isakmp_var.h"
#include "oakley.h"
/* Phase 1 handler */
/*
* main mode:
* initiator responder
* 0 (---) (---)
* 1 start start (1st msg received)
* 2 (---) 1st valid msg received
* 3 1st msg sent 1st msg sent
* 4 1st valid msg received 2st valid msg received
* 5 2nd msg sent 2nd msg sent
* 6 2nd valid msg received 3rd valid msg received
* 7 3rd msg sent 3rd msg sent
* 8 3rd valid msg received (---)
* 9 SA established SA established
*
* aggressive mode:
* initiator responder
* 0 (---) (---)
* 1 start start (1st msg received)
* 2 (---) 1st valid msg received
* 3 1st msg sent 1st msg sent
* 4 1st valid msg received 2st valid msg received
* 5 (---) (---)
* 6 (---) (---)
* 7 (---) (---)
* 8 (---) (---)
* 9 SA established SA established
*
* base mode:
* initiator responder
* 0 (---) (---)
* 1 start start (1st msg received)
* 2 (---) 1st valid msg received
* 3 1st msg sent 1st msg sent
* 4 1st valid msg received 2st valid msg received
* 5 2nd msg sent (---)
* 6 (---) (---)
* 7 (---) (---)
* 8 (---) (---)
* 9 SA established SA established
*/
#define PHASE1ST_SPAWN 0
#define PHASE1ST_START 1
#define PHASE1ST_MSG1RECEIVED 2
#define PHASE1ST_MSG1SENT 3
#define PHASE1ST_MSG2RECEIVED 4
#define PHASE1ST_MSG2SENT 5
#define PHASE1ST_MSG3RECEIVED 6
#define PHASE1ST_MSG3SENT 7
#define PHASE1ST_MSG4RECEIVED 8
#define PHASE1ST_ESTABLISHED 9
#define PHASE1ST_EXPIRED 10
#define PHASE1ST_MAX 11
/* About address semantics in each case.
* initiator(addr=I) responder(addr=R)
* src dst src dst
* (local) (remote) (local) (remote)
* phase 1 handler I R R I
* phase 2 handler I R R I
* getspi msg R I I R
* acquire msg I R
* ID payload I R I R
*/
#ifdef ENABLE_HYBRID
struct isakmp_cfg_state;
#endif
struct ph1handle {
isakmp_index index;
int status; /* status of this SA */
int side; /* INITIATOR or RESPONDER */
struct sockaddr *remote; /* remote address to negosiate ph1 */
struct sockaddr *local; /* local address to negosiate ph1 */
/* XXX copy from rmconf due to anonymous configuration.
* If anonymous will be forbidden, we do delete them. */
struct remoteconf *rmconf; /* pointer to remote configuration */
struct isakmpsa *approval; /* pointer to SA(s) approved. */
vchar_t *authstr; /* place holder of string for auth. */
/* for example pre-shared key */
u_int8_t version; /* ISAKMP version */
u_int8_t etype; /* Exchange type actually for use */
u_int8_t flags; /* Flags */
u_int32_t msgid; /* message id */
struct ph1natt_options *natt_options; /* Selected NAT-T IKE version */
u_int32_t natt_flags; /* NAT-T related flags */
#ifdef ENABLE_FRAG
int frag; /* IKE phase 1 fragmentation */
struct isakmp_frag_item *frag_chain; /* Received fragments */
#endif
struct sched *sce; /* schedule for expire */
struct sched *scr; /* schedule for resend */
int retry_counter; /* for resend. */
vchar_t *sendbuf; /* buffer for re-sending */
vchar_t *dhpriv; /* DH; private value */
vchar_t *dhpub; /* DH; public value */
vchar_t *dhpub_p; /* DH; partner's public value */
vchar_t *dhgxy; /* DH; shared secret */
vchar_t *nonce; /* nonce value */
vchar_t *nonce_p; /* partner's nonce value */
vchar_t *skeyid; /* SKEYID */
vchar_t *skeyid_d; /* SKEYID_d */
vchar_t *skeyid_a; /* SKEYID_a, i.e. hash */
vchar_t *skeyid_e; /* SKEYID_e, i.e. encryption */
vchar_t *key; /* cipher key */
vchar_t *hash; /* HASH minus general header */
vchar_t *sig; /* SIG minus general header */
vchar_t *sig_p; /* peer's SIG minus general header */
cert_t *cert; /* CERT minus general header */
cert_t *cert_p; /* peer's CERT minus general header */
cert_t *crl_p; /* peer's CRL minus general header */
cert_t *cr_p; /* peer's CR not including general */
RSA *rsa; /* my RSA key */
RSA *rsa_p; /* peer's RSA key */
struct genlist *rsa_candidates; /* possible candidates for peer's RSA key */
vchar_t *id; /* ID minus gen header */
vchar_t *id_p; /* partner's ID minus general header */
/* i.e. strut ipsecdoi_id_b*. */
struct isakmp_ivm *ivm; /* IVs */
vchar_t *sa; /* whole SA payload to send/to be sent*/
/* to calculate HASH */
/* NOT INCLUDING general header. */
vchar_t *sa_ret; /* SA payload to reply/to be replyed */
/* NOT INCLUDING general header. */
/* NOTE: Should be release after use. */
#ifdef HAVE_GSSAPI
void *gssapi_state; /* GSS-API specific state. */
/* Allocated when needed */
vchar_t *gi_i; /* optional initiator GSS id */
vchar_t *gi_r; /* optional responder GSS id */
#endif
struct isakmp_pl_hash *pl_hash; /* pointer to hash payload */
time_t created; /* timestamp for establish */
#ifdef ENABLE_STATS
struct timeval start;
struct timeval end;
#endif
int dpd_support; /* Does remote supports DPD ? */
time_t dpd_lastack; /* Last ack received */
u_int16_t dpd_seq; /* DPD seq number to receive */
u_int8_t dpd_fails; /* number of failures */
struct sched *dpd_r_u;
u_int32_t msgid2; /* msgid counter for Phase 2 */
int ph2cnt; /* the number which is negotiated by this phase 1 */
LIST_HEAD(_ph2ofph1_, ph2handle) ph2tree;
LIST_ENTRY(ph1handle) chain;
#ifdef ENABLE_HYBRID
struct isakmp_cfg_state *mode_cfg; /* ISAKMP mode config state */
#endif
};
/* Phase 2 handler */
/* allocated per a SA or SA bundles of a pair of peer's IP addresses. */
/*
* initiator responder
* 0 (---) (---)
* 1 start start (1st msg received)
* 2 acquire msg get 1st valid msg received
* 3 getspi request sent getspi request sent
* 4 getspi done getspi done
* 5 1st msg sent 1st msg sent
* 6 1st valid msg received 2nd valid msg received
* 7 (commit bit) (commit bit)
* 8 SAs added SAs added
* 9 SAs established SAs established
* 10 SAs expired SAs expired
*/
#define PHASE2ST_SPAWN 0
#define PHASE2ST_START 1
#define PHASE2ST_STATUS2 2
#define PHASE2ST_GETSPISENT 3
#define PHASE2ST_GETSPIDONE 4
#define PHASE2ST_MSG1SENT 5
#define PHASE2ST_STATUS6 6
#define PHASE2ST_COMMIT 7
#define PHASE2ST_ADDSA 8
#define PHASE2ST_ESTABLISHED 9
#define PHASE2ST_EXPIRED 10
#define PHASE2ST_MAX 11
struct ph2handle {
struct sockaddr *src; /* my address of SA. */
struct sockaddr *dst; /* peer's address of SA. */
/*
* copy ip address from ID payloads when ID type is ip address.
* In other case, they must be null.
*/
struct sockaddr *src_id;
struct sockaddr *dst_id;
u_int32_t spid; /* policy id by kernel */
int status; /* ipsec sa status */
u_int8_t side; /* INITIATOR or RESPONDER */
struct sched *sce; /* schedule for expire */
struct sched *scr; /* schedule for resend */
int retry_counter; /* for resend. */
vchar_t *sendbuf; /* buffer for re-sending */
vchar_t *msg1; /* buffer for re-sending */
/* used for responder's first message */
int retry_checkph1; /* counter to wait phase 1 finished. */
/* NOTE: actually it's timer. */
u_int32_t seq; /* sequence number used by PF_KEY */
/*
* NOTE: In responder side, we can't identify each SAs
* with same destination address for example, when
* socket based SA is required. So we set a identifier
* number to "seq", and sent kernel by pfkey.
*/
u_int8_t satype; /* satype in PF_KEY */
/*
* saved satype in the original PF_KEY request from
* the kernel in order to reply a error.
*/
u_int8_t flags; /* Flags for phase 2 */
u_int32_t msgid; /* msgid for phase 2 */
struct sainfo *sainfo; /* place holder of sainfo */
struct saprop *proposal; /* SA(s) proposal. */
struct saprop *approval; /* SA(s) approved. */
caddr_t spidx_gen; /* policy from peer's proposal */
struct dhgroup *pfsgrp; /* DH; prime number */
vchar_t *dhpriv; /* DH; private value */
vchar_t *dhpub; /* DH; public value */
vchar_t *dhpub_p; /* DH; partner's public value */
vchar_t *dhgxy; /* DH; shared secret */
vchar_t *id; /* ID minus gen header */
vchar_t *id_p; /* peer's ID minus general header */
vchar_t *nonce; /* nonce value in phase 2 */
vchar_t *nonce_p; /* partner's nonce value in phase 2 */
vchar_t *sa; /* whole SA payload to send/to be sent*/
/* to calculate HASH */
/* NOT INCLUDING general header. */
vchar_t *sa_ret; /* SA payload to reply/to be replyed */
/* NOT INCLUDING general header. */
/* NOTE: Should be release after use. */
struct isakmp_ivm *ivm; /* IVs */
#ifdef ENABLE_STATS
struct timeval start;
struct timeval end;
#endif
struct ph1handle *ph1; /* back pointer to isakmp status */
LIST_ENTRY(ph2handle) chain;
LIST_ENTRY(ph2handle) ph1bind; /* chain to ph1handle */
};
/*
* for handling initial contact.
*/
struct contacted {
struct sockaddr *remote; /* remote address to negosiate ph1 */
LIST_ENTRY(contacted) chain;
};
/*
* for checking a packet retransmited.
*/
struct recvdpkt {
struct sockaddr *remote; /* the remote address */
struct sockaddr *local; /* the local address */
vchar_t *hash; /* hash of the received packet */
vchar_t *sendbuf; /* buffer for the response */
int retry_counter; /* how many times to send */
time_t time_send; /* timestamp to send a packet */
time_t created; /* timestamp to create a queue */
struct sched *scr; /* schedule for resend, may not used */
LIST_ENTRY(recvdpkt) chain;
};
/* for parsing ISAKMP header. */
struct isakmp_parse_t {
u_char type; /* payload type of mine */
int len; /* ntohs(ptr->len) */
struct isakmp_gen *ptr;
};
/*
* for IV management.
*
* - normal case
* initiator responder
* ------------------------- --------------------------
* initialize iv(A), ive(A). initialize iv(A), ive(A).
* encode by ive(A).
* save to iv(B). ---[packet(B)]--> save to ive(B).
* decode by iv(A).
* packet consistency.
* sync iv(B) with ive(B).
* check auth, integrity.
* encode by ive(B).
* save to ive(C). <--[packet(C)]--- save to iv(C).
* decoded by iv(B).
* :
*
* - In the case that a error is found while cipher processing,
* initiator responder
* ------------------------- --------------------------
* initialize iv(A), ive(A). initialize iv(A), ive(A).
* encode by ive(A).
* save to iv(B). ---[packet(B)]--> save to ive(B).
* decode by iv(A).
* packet consistency.
* sync iv(B) with ive(B).
* check auth, integrity.
* error found.
* create notify.
* get ive2(X) from iv(B).
* encode by ive2(X).
* get iv2(X) from iv(B). <--[packet(Y)]--- save to iv2(Y).
* save to ive2(Y).
* decoded by iv2(X).
* :
*
* The reason why the responder synchronizes iv with ive after checking the
* packet consistency is that it is required to leave the IV for decoding
* packet. Because there is a potential of error while checking the packet
* consistency. Also the reason why that is before authentication and
* integirty check is that the IV for informational exchange has to be made
* by the IV which is after packet decoded and checking the packet consistency.
* Otherwise IV mismatched happens between the intitiator and the responder.
*/
struct isakmp_ivm {
vchar_t *iv; /* for decoding packet */
/* if phase 1, it's for computing phase2 iv */
vchar_t *ive; /* for encoding packet */
};
/* for dumping */
struct ph1dump {
isakmp_index index;
int status;
int side;
struct sockaddr_storage remote;
struct sockaddr_storage local;
u_int8_t version;
u_int8_t etype;
time_t created;
int ph2cnt;
};
struct sockaddr;
struct ph1handle;
struct ph2handle;
struct policyindex;
extern struct ph1handle *getph1byindex __P((isakmp_index *));
extern struct ph1handle *getph1byindex0 __P((isakmp_index *));
extern struct ph1handle *getph1byaddr __P((struct sockaddr *,
struct sockaddr *));
extern struct ph1handle *getph1bydstaddr __P((struct sockaddr *));
extern vchar_t *dumpph1 __P((void));
extern struct ph1handle *newph1 __P((void));
extern void delph1 __P((struct ph1handle *));
extern int insph1 __P((struct ph1handle *));
extern void remph1 __P((struct ph1handle *));
extern void flushph1 __P((void));
extern void initph1tree __P((void));
extern struct ph2handle *getph2byspidx __P((struct policyindex *));
extern struct ph2handle *getph2byspid __P((u_int32_t));
extern struct ph2handle *getph2byseq __P((u_int32_t));
extern struct ph2handle *getph2bymsgid __P((struct ph1handle *, u_int32_t));
extern struct ph2handle *getph2bysaidx __P((struct sockaddr *,
struct sockaddr *, u_int, u_int32_t));
extern struct ph2handle *newph2 __P((void));
extern void initph2 __P((struct ph2handle *));
extern void delph2 __P((struct ph2handle *));
extern int insph2 __P((struct ph2handle *));
extern void remph2 __P((struct ph2handle *));
extern void flushph2 __P((void));
extern void deleteallph2 __P((struct sockaddr *, struct sockaddr *, u_int));
extern void initph2tree __P((void));
extern void bindph12 __P((struct ph1handle *, struct ph2handle *));
extern void unbindph12 __P((struct ph2handle *));
extern struct contacted *getcontacted __P((struct sockaddr *));
extern int inscontacted __P((struct sockaddr *));
extern void initctdtree __P((void));
extern int check_recvdpkt __P((struct sockaddr *,
struct sockaddr *, vchar_t *));
extern int add_recvdpkt __P((struct sockaddr *, struct sockaddr *,
vchar_t *, vchar_t *));
extern void init_recvdpkt __P((void));
#ifdef ENABLE_HYBRID
extern int exclude_cfg_addr __P((const struct sockaddr *));
#endif
#endif /* _HANDLER_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,227 @@
/* $Id: ipsec_doi.h,v 1.1.1.1 2005/02/12 11:12:10 manu Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#ifndef _IPSEC_DOI_H
#define _IPSEC_DOI_H
/* refered to RFC2407 */
#define IPSEC_DOI 1
/* 4.2 IPSEC Situation Definition */
#define IPSECDOI_SIT_IDENTITY_ONLY 0x00000001
#define IPSECDOI_SIT_SECRECY 0x00000002
#define IPSECDOI_SIT_INTEGRITY 0x00000004
/* 4.4.1 IPSEC Security Protocol Identifiers */
/* 4.4.2 IPSEC ISAKMP Transform Values */
#define IPSECDOI_PROTO_ISAKMP 1
#define IPSECDOI_KEY_IKE 1
/* 4.4.1 IPSEC Security Protocol Identifiers */
#define IPSECDOI_PROTO_IPSEC_AH 2
/* 4.4.3 IPSEC AH Transform Values */
#define IPSECDOI_AH_MD5 2
#define IPSECDOI_AH_SHA 3
#define IPSECDOI_AH_DES 4
#define IPSECDOI_AH_SHA2_256 5
#define IPSECDOI_AH_SHA2_384 6
#define IPSECDOI_AH_SHA2_512 7
/* 4.4.1 IPSEC Security Protocol Identifiers */
#define IPSECDOI_PROTO_IPSEC_ESP 3
/* 4.4.4 IPSEC ESP Transform Identifiers */
#define IPSECDOI_ESP_DES_IV64 1
#define IPSECDOI_ESP_DES 2
#define IPSECDOI_ESP_3DES 3
#define IPSECDOI_ESP_RC5 4
#define IPSECDOI_ESP_IDEA 5
#define IPSECDOI_ESP_CAST 6
#define IPSECDOI_ESP_BLOWFISH 7
#define IPSECDOI_ESP_3IDEA 8
#define IPSECDOI_ESP_DES_IV32 9
#define IPSECDOI_ESP_RC4 10
#define IPSECDOI_ESP_NULL 11
#define IPSECDOI_ESP_AES 12
#if 1
/* draft-ietf-ipsec-ciph-aes-cbc-00.txt */
#define IPSECDOI_ESP_TWOFISH 253
#else
/* SSH uses these value for now */
#define IPSECDOI_ESP_TWOFISH 250
#endif
/* 4.4.1 IPSEC Security Protocol Identifiers */
#define IPSECDOI_PROTO_IPCOMP 4
/* 4.4.5 IPSEC IPCOMP Transform Identifiers */
#define IPSECDOI_IPCOMP_OUI 1
#define IPSECDOI_IPCOMP_DEFLATE 2
#define IPSECDOI_IPCOMP_LZS 3
/* 4.5 IPSEC Security Association Attributes */
/* NOTE: default value is not included in a packet. */
#define IPSECDOI_ATTR_SA_LD_TYPE 1 /* B */
#define IPSECDOI_ATTR_SA_LD_TYPE_DEFAULT 1
#define IPSECDOI_ATTR_SA_LD_TYPE_SEC 1
#define IPSECDOI_ATTR_SA_LD_TYPE_KB 2
#define IPSECDOI_ATTR_SA_LD_TYPE_MAX 3
#define IPSECDOI_ATTR_SA_LD 2 /* V */
#define IPSECDOI_ATTR_SA_LD_SEC_DEFAULT 28800 /* 8 hours */
#define IPSECDOI_ATTR_SA_LD_KB_MAX (~(1 << ((sizeof(int) << 3) - 1)))
#define IPSECDOI_ATTR_GRP_DESC 3 /* B */
#define IPSECDOI_ATTR_ENC_MODE 4 /* B */
/* default value: host dependent */
#define IPSECDOI_ATTR_ENC_MODE_ANY 0 /* NOTE:internal use */
#define IPSECDOI_ATTR_ENC_MODE_TUNNEL 1
#define IPSECDOI_ATTR_ENC_MODE_TRNS 2
/* NAT-T draft-ietf-ipsec-nat-t-ike-05 and later */
#define IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_RFC 3
#define IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC 4
/* NAT-T up to draft-ietf-ipsec-nat-t-ike-04 */
#define IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_DRAFT 61443
#define IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT 61444
#define IPSECDOI_ATTR_AUTH 5 /* B */
/* 0 means not to use authentication. */
#define IPSECDOI_ATTR_AUTH_HMAC_MD5 1
#define IPSECDOI_ATTR_AUTH_HMAC_SHA1 2
#define IPSECDOI_ATTR_AUTH_DES_MAC 3
#define IPSECDOI_ATTR_AUTH_KPDK 4 /*RFC-1826(Key/Pad/Data/Key)*/
#define IPSECDOI_ATTR_SHA2_256 5
#define IPSECDOI_ATTR_SHA2_384 6
#define IPSECDOI_ATTR_SHA2_512 7
#define IPSECDOI_ATTR_AUTH_NONE 254 /* NOTE:internal use */
/*
* When negotiating ESP without authentication, the Auth
* Algorithm attribute MUST NOT be included in the proposal.
* When negotiating ESP without confidentiality, the Auth
* Algorithm attribute MUST be included in the proposal and
* the ESP transform ID must be ESP_NULL.
*/
#define IPSECDOI_ATTR_KEY_LENGTH 6 /* B */
#define IPSECDOI_ATTR_KEY_ROUNDS 7 /* B */
#define IPSECDOI_ATTR_COMP_DICT_SIZE 8 /* B */
#define IPSECDOI_ATTR_COMP_PRIVALG 9 /* V */
/* 4.6.1 Security Association Payload */
struct ipsecdoi_pl_sa {
struct isakmp_gen h;
struct ipsecdoi_sa_b {
u_int32_t doi; /* Domain of Interpretation */
u_int32_t sit; /* Situation */
} b;
/* followed by Leveled Domain Identifier and so on. */
} __attribute__((__packed__));
struct ipsecdoi_secrecy_h {
u_int16_t len;
u_int16_t reserved;
/* followed by the value */
} __attribute__((__packed__));
/* 4.6.2 Identification Payload Content */
struct ipsecdoi_pl_id {
struct isakmp_gen h;
struct ipsecdoi_id_b {
u_int8_t type; /* ID Type */
u_int8_t proto_id; /* Protocol ID */
u_int16_t port; /* Port */
} b;
/* followed by Identification Data */
} __attribute__((__packed__));
#define IPSECDOI_ID_IPV4_ADDR 1
#define IPSECDOI_ID_FQDN 2
#define IPSECDOI_ID_USER_FQDN 3
#define IPSECDOI_ID_IPV4_ADDR_SUBNET 4
#define IPSECDOI_ID_IPV6_ADDR 5
#define IPSECDOI_ID_IPV6_ADDR_SUBNET 6
#define IPSECDOI_ID_IPV4_ADDR_RANGE 7
#define IPSECDOI_ID_IPV6_ADDR_RANGE 8
#define IPSECDOI_ID_DER_ASN1_DN 9
#define IPSECDOI_ID_DER_ASN1_GN 10
#define IPSECDOI_ID_KEY_ID 11
/* compressing doi type, it's internal use. */
#define IDTYPE_UNDEFINED 0
#define IDTYPE_FQDN 1
#define IDTYPE_USERFQDN 2
#define IDTYPE_KEYID 3
#define IDTYPE_ADDRESS 4
#define IDTYPE_ASN1DN 5
#define IDTYPE_LOGIN 6
/* The use for checking proposal payload. This is not exchange type. */
#define IPSECDOI_TYPE_PH1 0
#define IPSECDOI_TYPE_PH2 1
struct isakmpsa;
struct ipsecdoi_pl_sa;
struct saprop;
struct saproto;
struct satrns;
struct prop_pair;
extern int ipsecdoi_checkph1proposal __P((vchar_t *, struct ph1handle *));
extern int ipsecdoi_selectph2proposal __P((struct ph2handle *));
extern int ipsecdoi_checkph2proposal __P((struct ph2handle *));
extern struct prop_pair **get_proppair __P((vchar_t *, int));
extern vchar_t *get_sabyproppair __P((struct prop_pair *, struct ph1handle *));
extern int ipsecdoi_updatespi __P((struct ph2handle *iph2));
extern vchar_t *get_sabysaprop __P((struct saprop *, vchar_t *));
extern int ipsecdoi_checkid1 __P((struct ph1handle *));
extern int ipsecdoi_setid1 __P((struct ph1handle *));
extern int set_identifier __P((vchar_t **, int, vchar_t *));
extern int ipsecdoi_setid2 __P((struct ph2handle *));
extern vchar_t *ipsecdoi_sockaddr2id __P((struct sockaddr *, u_int, u_int));
extern int ipsecdoi_id2sockaddr __P((vchar_t *, struct sockaddr *,
u_int8_t *, u_int16_t *));
extern const char *ipsecdoi_id2str __P((const vchar_t *));
extern vchar_t *ipsecdoi_setph1proposal __P((struct isakmpsa *));
extern int ipsecdoi_setph2proposal __P((struct ph2handle *));
extern int ipsecdoi_transportmode __P((struct saprop *));
extern int ipsecdoi_get_defaultlifetime __P((void));
extern int ipsecdoi_checkalgtypes __P((int, int, int, int));
extern int ipproto2doi __P((int));
extern int doi2ipproto __P((int));
extern int ipsecdoi_t2satrns __P((struct isakmp_pl_t *,
struct saprop *, struct saproto *, struct satrns *));
extern int ipsecdoi_authalg2trnsid __P((int));
extern int idtype2doi __P((int));
extern int doi2idtype __P((int));
#endif /* _IPSEC_DOI_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,425 @@
/* $Id: isakmp.h,v 1.1.1.1 2005/02/12 11:12:15 manu Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#ifndef _ISAKMP_H
#define _ISAKMP_H
/* refer to RFC 2408 */
/* must include <netinet/in.h> first. */
/* must include "isakmp_var.h" first. */
#define INITIATOR 0 /* synonym sender */
#define RESPONDER 1 /* synonym receiver */
#define GENERATE 1
#define VALIDATE 0
/* 3.1 ISAKMP Header Format
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! Initiator !
! Cookie !
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! Responder !
! Cookie !
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! Next Payload ! MjVer ! MnVer ! Exchange Type ! Flags !
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! Message ID !
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! Length !
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
struct isakmp {
cookie_t i_ck; /* Initiator Cookie */
cookie_t r_ck; /* Responder Cookie */
u_int8_t np; /* Next Payload Type */
u_int8_t v;
u_int8_t etype; /* Exchange Type */
u_int8_t flags; /* Flags */
u_int32_t msgid;
u_int32_t len; /* Length */
} __attribute__((__packed__));
/* Next Payload Type */
#define ISAKMP_NPTYPE_NONE 0 /* NONE*/
#define ISAKMP_NPTYPE_SA 1 /* Security Association */
#define ISAKMP_NPTYPE_P 2 /* Proposal */
#define ISAKMP_NPTYPE_T 3 /* Transform */
#define ISAKMP_NPTYPE_KE 4 /* Key Exchange */
#define ISAKMP_NPTYPE_ID 5 /* Identification */
#define ISAKMP_NPTYPE_CERT 6 /* Certificate */
#define ISAKMP_NPTYPE_CR 7 /* Certificate Request */
#define ISAKMP_NPTYPE_HASH 8 /* Hash */
#define ISAKMP_NPTYPE_SIG 9 /* Signature */
#define ISAKMP_NPTYPE_NONCE 10 /* Nonce */
#define ISAKMP_NPTYPE_N 11 /* Notification */
#define ISAKMP_NPTYPE_D 12 /* Delete */
#define ISAKMP_NPTYPE_VID 13 /* Vendor ID */
#define ISAKMP_NPTYPE_ATTR 14 /* Attribute */
/* NAT-T draft-ietf-ipsec-nat-t-ike-05 and later */
/* XXX conflicts with values assigned to RFC 3547 */
#define ISAKMP_NPTYPE_NATD_BADDRAFT 15 /* NAT Discovery */
#define ISAKMP_NPTYPE_NATOA_BADDRAFT 16 /* NAT Original Address */
/* NAT-T RFC */
#define ISAKMP_NPTYPE_NATD_RFC 20 /* NAT Discovery */
#define ISAKMP_NPTYPE_NATOA_RFC 21 /* NAT Original Address */
/* NAT-T up to draft-ietf-ipsec-nat-t-ike-04 */
#define ISAKMP_NPTYPE_NATD_DRAFT 130 /* NAT Discovery */
#define ISAKMP_NPTYPE_NATOA_DRAFT 131 /* NAT Original Address */
/* Frag does not seems to be documented */
#define ISAKMP_NPTYPE_FRAG 132 /* IKE fragmentation payload */
#define ISAKMP_NPTYPE_MAX 17
/* 128 - 255 Private Use */
/*
* The following are valid when the Vendor ID is one of the
* following:
*
* MD5("A GSS-API Authentication Method for IKE")
* MD5("GSSAPI") (recognized by Windows 2000)
* MD5("MS NT5 ISAKMPOAKLEY") (sent by Windows 2000)
*
* See draft-ietf-ipsec-isakmp-gss-auth-06.txt.
*/
#define ISAKMP_NPTYPE_GSS 129 /* GSS token */
#define ISAKMP_MAJOR_VERSION 1
#define ISAKMP_MINOR_VERSION 0
#define ISAKMP_VERSION_NUMBER 0x10
#define ISAKMP_GETMAJORV(v) (((v) & 0xf0) >> 4)
#define ISAKMP_SETMAJORV(v, m) ((v) = ((v) & 0x0f) | (((m) << 4) & 0xf0))
#define ISAKMP_GETMINORV(v) ((v) & 0x0f)
#define ISAKMP_SETMINORV(v, m) ((v) = ((v) & 0xf0) | ((m) & 0x0f))
/* Exchange Type */
#define ISAKMP_ETYPE_NONE 0 /* NONE */
#define ISAKMP_ETYPE_BASE 1 /* Base */
#define ISAKMP_ETYPE_IDENT 2 /* Identity Proteciton */
#define ISAKMP_ETYPE_AUTH 3 /* Authentication Only */
#define ISAKMP_ETYPE_AGG 4 /* Aggressive */
#define ISAKMP_ETYPE_INFO 5 /* Informational */
#define ISAKMP_ETYPE_CFG 6 /* Mode config */
/* Additional Exchange Type */
#define ISAKMP_ETYPE_QUICK 32 /* Quick Mode */
#define ISAKMP_ETYPE_NEWGRP 33 /* New group Mode */
#define ISAKMP_ETYPE_ACKINFO 34 /* Acknowledged Informational */
/* Flags */
#define ISAKMP_FLAG_E 0x01 /* Encryption Bit */
#define ISAKMP_FLAG_C 0x02 /* Commit Bit */
#define ISAKMP_FLAG_A 0x04 /* Authentication Only Bit */
/* 3.2 Payload Generic Header
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
! Next Payload ! RESERVED ! Payload Length !
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
struct isakmp_gen {
u_int8_t np; /* Next Payload */
u_int8_t reserved; /* RESERVED, unused, must set to 0 */
u_int16_t len; /* Payload Length */
} __attribute__((__packed__));
/* 3.3 Data Attributes
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
!A! Attribute Type ! AF=0 Attribute Length !
!F! ! AF=1 Attribute Value !
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
. AF=0 Attribute Value .
. AF=1 Not Transmitted .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
struct isakmp_data {
u_int16_t type; /* defined by DOI-spec, and Attribute Format */
u_int16_t lorv; /* if f equal 1, Attribute Length */
/* if f equal 0, Attribute Value */
/* if f equal 1, Attribute Value */
} __attribute__((__packed__));
#define ISAKMP_GEN_TLV 0x0000
#define ISAKMP_GEN_TV 0x8000
/* mask for type of attribute format */
#define ISAKMP_GEN_MASK 0x8000
#if 0
/* MAY NOT be used, because of being defined in ipsec-doi. */
/* 3.4 Security Association Payload */
struct isakmp_pl_sa {
struct isakmp_gen h;
u_int32_t doi; /* Domain of Interpretation */
u_int32_t sit; /* Situation */
} __attribute__((__packed__));
#endif
/* 3.5 Proposal Payload */
/*
The value of the next payload field MUST only contain the value "2"
or "0". If there are additional Proposal payloads in the message,
then this field will be 2. If the current Proposal payload is the
last within the security association proposal, then this field will
be 0.
*/
struct isakmp_pl_p {
struct isakmp_gen h;
u_int8_t p_no; /* Proposal # */
u_int8_t proto_id; /* Protocol */
u_int8_t spi_size; /* SPI Size */
u_int8_t num_t; /* Number of Transforms */
/* SPI */
} __attribute__((__packed__));
/* 3.6 Transform Payload */
/*
The value of the next payload field MUST only contain the value "3"
or "0". If there are additional Transform payloads in the proposal,
then this field will be 3. If the current Transform payload is the
last within the proposal, then this field will be 0.
*/
struct isakmp_pl_t {
struct isakmp_gen h;
u_int8_t t_no; /* Transform # */
u_int8_t t_id; /* Transform-Id */
u_int16_t reserved; /* RESERVED2 */
/* SA Attributes */
} __attribute__((__packed__));
/* 3.7 Key Exchange Payload */
struct isakmp_pl_ke {
struct isakmp_gen h;
/* Key Exchange Data */
} __attribute__((__packed__));
#if 0
/* NOTE: MUST NOT use because of being defined in ipsec-doi instead them. */
/* 3.8 Identification Payload */
struct isakmp_pl_id {
struct isakmp_gen h;
union {
u_int8_t id_type; /* ID Type */
u_int32_t doi_data; /* DOI Specific ID Data */
} d;
/* Identification Data */
} __attribute__((__packed__));
/* A.4 ISAKMP Identification Type Values */
#define ISAKMP_ID_IPV4_ADDR 0
#define ISAKMP_ID_IPV4_ADDR_SUBNET 1
#define ISAKMP_ID_IPV6_ADDR 2
#define ISAKMP_ID_IPV6_ADDR_SUBNET 3
#endif
/* 3.9 Certificate Payload */
struct isakmp_pl_cert {
struct isakmp_gen h;
/*
* Encoding type of 1 octet follows immediately,
* variable length CERT data follows encoding type.
*/
} __attribute__((__packed__));
/* Certificate Type */
#define ISAKMP_CERT_NONE 0
#define ISAKMP_CERT_PKCS7 1
#define ISAKMP_CERT_PGP 2
#define ISAKMP_CERT_DNS 3
#define ISAKMP_CERT_X509SIGN 4
#define ISAKMP_CERT_X509KE 5
#define ISAKMP_CERT_KERBEROS 6
#define ISAKMP_CERT_CRL 7
#define ISAKMP_CERT_ARL 8
#define ISAKMP_CERT_SPKI 9
#define ISAKMP_CERT_X509ATTR 10
#define ISAKMP_CERT_PLAINRSA 11
/* the method to get peers certificate */
#define ISAKMP_GETCERT_PAYLOAD 1
#define ISAKMP_GETCERT_LOCALFILE 2
#define ISAKMP_GETCERT_DNS 3
/* 3.10 Certificate Request Payload */
struct isakmp_pl_cr {
struct isakmp_gen h;
u_int8_t num_cert; /* # Cert. Types */
/*
Certificate Types (variable length)
-- Contains a list of the types of certificates requested,
sorted in order of preference. Each individual certificate
type is 1 octet. This field is NOT required.
*/
/* # Certificate Authorities (1 octet) */
/* Certificate Authorities (variable length) */
} __attribute__((__packed__));
/* 3.11 Hash Payload */
struct isakmp_pl_hash {
struct isakmp_gen h;
/* Hash Data */
} __attribute__((__packed__));
/* 3.12 Signature Payload */
struct isakmp_pl_sig {
struct isakmp_gen h;
/* Signature Data */
} __attribute__((__packed__));
/* 3.13 Nonce Payload */
struct isakmp_pl_nonce {
struct isakmp_gen h;
/* Nonce Data */
} __attribute__((__packed__));
/* 3.14 Notification Payload */
struct isakmp_pl_n {
struct isakmp_gen h;
u_int32_t doi; /* Domain of Interpretation */
u_int8_t proto_id; /* Protocol-ID */
u_int8_t spi_size; /* SPI Size */
u_int16_t type; /* Notify Message Type */
/* SPI */
/* Notification Data */
} __attribute__((__packed__));
/* 3.14.1 Notify Message Types */
/* NOTIFY MESSAGES - ERROR TYPES */
#define ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE 1
#define ISAKMP_NTYPE_DOI_NOT_SUPPORTED 2
#define ISAKMP_NTYPE_SITUATION_NOT_SUPPORTED 3
#define ISAKMP_NTYPE_INVALID_COOKIE 4
#define ISAKMP_NTYPE_INVALID_MAJOR_VERSION 5
#define ISAKMP_NTYPE_INVALID_MINOR_VERSION 6
#define ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE 7
#define ISAKMP_NTYPE_INVALID_FLAGS 8
#define ISAKMP_NTYPE_INVALID_MESSAGE_ID 9
#define ISAKMP_NTYPE_INVALID_PROTOCOL_ID 10
#define ISAKMP_NTYPE_INVALID_SPI 11
#define ISAKMP_NTYPE_INVALID_TRANSFORM_ID 12
#define ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED 13
#define ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN 14
#define ISAKMP_NTYPE_BAD_PROPOSAL_SYNTAX 15
#define ISAKMP_NTYPE_PAYLOAD_MALFORMED 16
#define ISAKMP_NTYPE_INVALID_KEY_INFORMATION 17
#define ISAKMP_NTYPE_INVALID_ID_INFORMATION 18
#define ISAKMP_NTYPE_INVALID_CERT_ENCODING 19
#define ISAKMP_NTYPE_INVALID_CERTIFICATE 20
#define ISAKMP_NTYPE_BAD_CERT_REQUEST_SYNTAX 21
#define ISAKMP_NTYPE_INVALID_CERT_AUTHORITY 22
#define ISAKMP_NTYPE_INVALID_HASH_INFORMATION 23
#define ISAKMP_NTYPE_AUTHENTICATION_FAILED 24
#define ISAKMP_NTYPE_INVALID_SIGNATURE 25
#define ISAKMP_NTYPE_ADDRESS_NOTIFICATION 26
#define ISAKMP_NTYPE_NOTIFY_SA_LIFETIME 27
#define ISAKMP_NTYPE_CERTIFICATE_UNAVAILABLE 28
#define ISAKMP_NTYPE_UNSUPPORTED_EXCHANGE_TYPE 29
#define ISAKMP_NTYPE_UNEQUAL_PAYLOAD_LENGTHS 30
/* NOTIFY MESSAGES - STATUS TYPES */
#define ISAKMP_NTYPE_CONNECTED 16384
/* 4.6.3 IPSEC DOI Notify Message Types */
#define ISAKMP_NTYPE_RESPONDER_LIFETIME 24576
#define ISAKMP_NTYPE_REPLAY_STATUS 24577
#define ISAKMP_NTYPE_INITIAL_CONTACT 24578
/* DPD */
#define ISAKMP_NTYPE_R_U_THERE 36136
#define ISAKMP_NTYPE_R_U_THERE_ACK 36137
#define ISAKMP_NTYPE_HEARTBEAT 40503
/* using only to log */
#define ISAKMP_LOG_RETRY_LIMIT_REACHED 65530
/* XXX means internal error but it's not reserved by any drafts... */
#define ISAKMP_INTERNAL_ERROR -1
/* 3.15 Delete Payload */
struct isakmp_pl_d {
struct isakmp_gen h;
u_int32_t doi; /* Domain of Interpretation */
u_int8_t proto_id; /* Protocol-Id */
u_int8_t spi_size; /* SPI Size */
u_int16_t num_spi; /* # of SPIs */
/* SPI(es) */
} __attribute__((__packed__));
struct payload_list {
struct payload_list *next, *prev;
vchar_t *payload;
int payload_type;
};
/* See draft-ietf-ipsec-isakmp-mode-cfg-04.txt, 3.2 */
struct isakmp_pl_attr {
struct isakmp_gen h;
u_int8_t type; /* Exchange type */
u_int8_t res2;
u_int16_t id; /* Per transaction id */
} __attribute__((__packed__));
/* Exchange type */
#define ISAKMP_CFG_REQUEST 1
#define ISAKMP_CFG_REPLY 2
#define ISAKMP_CFG_SET 3
#define ISAKMP_CFG_ACK 4
/* IKE fragmentation payload */
struct isakmp_frag {
u_int16_t unknown0; /* always set to zero? */
u_int16_t len;
u_int16_t unknown1; /* always set to 1? */
u_int8_t index;
u_int8_t flags;
} __attribute__((__packed__));
/* flags */
#define ISAKMP_FRAG_LAST 1
/* DPD R-U-THERE / R-U-THERE-ACK Payload */
struct isakmp_pl_ru {
struct isakmp_gen h;
u_int32_t doi; /* Domain of Interpretation */
u_int8_t proto_id; /* Protocol-Id */
u_int8_t spi_size; /* SPI Size */
u_int16_t type; /* Notify type */
cookie_t i_ck; /* Initiator Cookie */
cookie_t r_ck; /* Responder cookie*/
u_int32_t data; /* Notification data */
} __attribute__((__packed__));
#endif /* _ISAKMP_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,44 @@
/* $Id: isakmp_agg.h,v 1.1.1.1 2005/02/12 11:12:17 manu Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#ifndef _ISAKMP_AGG_H
#define _ISAKMP_AGG_H
extern int agg_i1send __P((struct ph1handle *, vchar_t *));
extern int agg_i2recv __P((struct ph1handle *, vchar_t *));
extern int agg_i2send __P((struct ph1handle *, vchar_t *));
extern int agg_r1recv __P((struct ph1handle *, vchar_t *));
extern int agg_r1send __P((struct ph1handle *, vchar_t *));
extern int agg_r2recv __P((struct ph1handle *, vchar_t *));
extern int agg_r2send __P((struct ph1handle *, vchar_t *));
#endif /* _ISAKMP_AGG_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,46 @@
/* $Id: isakmp_base.h,v 1.1.1.1 2005/02/12 11:12:17 manu Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#ifndef _ISAKMP_BASE_H
#define _ISAKMP_BASE_H
extern int base_i1send __P((struct ph1handle *, vchar_t *));
extern int base_i2recv __P((struct ph1handle *, vchar_t *));
extern int base_i2send __P((struct ph1handle *, vchar_t *));
extern int base_i3recv __P((struct ph1handle *, vchar_t *));
extern int base_i3send __P((struct ph1handle *, vchar_t *));
extern int base_r1recv __P((struct ph1handle *, vchar_t *));
extern int base_r1send __P((struct ph1handle *, vchar_t *));
extern int base_r2recv __P((struct ph1handle *, vchar_t *));
extern int base_r2send __P((struct ph1handle *, vchar_t *));
#endif /* _ISAKMP_BASE_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,169 @@
/* $KAME$ */
/*
* Copyright (C) 2004 Emmanuel Dreyfus
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#ifdef HAVE_LIBPAM
#include <security/pam_appl.h>
#endif
/*
* XXX don't forget to update
* src/racoon/handler.c:exclude_cfg_addr()
* if you add IPv6 capability
*/
/* Attribute types */
#define INTERNAL_IP4_ADDRESS 1
#define INTERNAL_IP4_NETMASK 2
#define INTERNAL_IP4_DNS 3
#define INTERNAL_IP4_NBNS 4
#define INTERNAL_ADDRESS_EXPIRY 5
#define INTERNAL_IP4_DHCP 6
#define APPLICATION_VERSION 7
#define INTERNAL_IP6_ADDRESS 8
#define INTERNAL_IP6_NETMASK 9
#define INTERNAL_IP6_DNS 10
#define INTERNAL_IP6_NBNS 11
#define INTERNAL_IP6_DHCP 12
#define INTERNAL_IP4_SUBNET 13
#define SUPPORTED_ATTRIBUTES 14
#define INTERNAL_IP6_SUBNET 15
/* For APPLICATION_VERSION */
#define ISAKMP_CFG_RACOON_VERSION "KAME/racoon " \
"+ Hybrid auth Patches <manu@netbsd.org>"
/*
* Global configuration for ISAKMP mode confiration address allocation
* Readen from the mode_cfg section of racoon.conf
*/
struct isakmp_cfg_port {
char used;
#ifdef HAVE_LIBPAM
pam_handle_t *pam;
#endif
};
struct isakmp_cfg_config {
in_addr_t network4;
in_addr_t netmask4;
in_addr_t dns4;
in_addr_t nbns4;
struct isakmp_cfg_port *port_pool;
int authsource;
int confsource;
int accounting;
size_t pool_size;
int auth_throttle;
char motd[MAXPATHLEN + 1];
};
/* For authsource */
#define ISAKMP_CFG_AUTH_SYSTEM 0
#define ISAKMP_CFG_AUTH_RADIUS 1
#define ISAKMP_CFG_AUTH_PAM 2
/* For confsource */
#define ISAKMP_CFG_CONF_LOCAL 0
#define ISAKMP_CFG_CONF_RADIUS 1
/* For accounting */
#define ISAKMP_CFG_ACCT_NONE 0
#define ISAKMP_CFG_ACCT_RADIUS 1
#define ISAKMP_CFG_ACCT_PAM 2
/* For pool_size */
#define ISAKMP_CFG_MAX_CNX 255
/* For motd */
#define ISAKMP_CFG_MOTD "/etc/motd"
extern struct isakmp_cfg_config isakmp_cfg_config;
/*
* ISAKMP mode config state
*/
#define LOGINLEN 31
struct isakmp_cfg_state {
int flags; /* See below */
unsigned int port; /* address index */
char login[LOGINLEN + 1]; /* login */
struct in_addr addr4; /* IPv4 address */
struct in_addr mask4; /* IPv4 netmask */
struct in_addr dns4; /* IPv4 DNS (when client only) */
struct in_addr wins4; /* IPv4 WINS (when client only) */
struct xauth_state xauth; /* Xauth state, if revelant */
struct isakmp_ivm *ivm; /* XXX Use iph1's ivm? */
};
/* flags */
#define ISAKMP_CFG_VENDORID_XAUTH 0x01 /* Supports Xauth */
#define ISAKMP_CFG_VENDORID_UNITY 0x02 /* Cisco Unity compliant */
#define ISAKMP_CFG_PORT_ALLOCATED 0x04 /* Port allocated */
#define ISAKMP_CFG_ADDR4_RADIUS 0x08 /* Address from RADIUS */
#define ISAKMP_CFG_MASK4_RADIUS 0x10 /* Netmask from RADIUS */
#define ISAKMP_CFG_ADDR4_LOCAL 0x20 /* Address from local pool */
#define ISAKMP_CFG_MASK4_LOCAL 0x40 /* Netmask from local pool */
#define ISAKMP_CFG_GOT_ADDR4 0x80 /* Client got address */
#define ISAKMP_CFG_GOT_MASK4 0x100 /* Client got mask */
#define ISAKMP_CFG_GOT_DNS4 0x200 /* Client got DNS */
#define ISAKMP_CFG_GOT_WINS4 0x400 /* Client got WINS */
#define ISAKMP_CFG_DELETE_PH1 0x800 /* phase 1 should be deleted */
struct isakmp_pl_attr;
struct ph1handle;
struct isakmp_ivm;
void isakmp_cfg_r(struct ph1handle *, vchar_t *);
int isakmp_cfg_attr_r(struct ph1handle *, u_int32_t, struct isakmp_pl_attr *);
int isakmp_cfg_reply(struct ph1handle *, struct isakmp_pl_attr *);
int isakmp_cfg_request(struct ph1handle *, struct isakmp_pl_attr *);
int isakmp_cfg_set(struct ph1handle *, struct isakmp_pl_attr *);
int isakmp_cfg_send(struct ph1handle *, vchar_t *, u_int32_t, int, int);
struct isakmp_ivm *isakmp_cfg_newiv(struct ph1handle *, u_int32_t);
void isakmp_cfg_rmstate(struct ph1handle *);
struct isakmp_cfg_state *isakmp_cfg_mkstate(void);
vchar_t *isakmp_cfg_copy(struct ph1handle *, struct isakmp_data *);
vchar_t *isakmp_cfg_short(struct ph1handle *, struct isakmp_data *, int);
vchar_t *isakmp_cfg_string(struct ph1handle *, struct isakmp_data *, char *);
int isakmp_cfg_getconfig(struct ph1handle *);
int isakmp_cfg_setenv(struct ph1handle *, char ***, int *);
int isakmp_cfg_getport(struct ph1handle *);
int isakmp_cfg_putport(struct ph1handle *, unsigned int);
#ifdef HAVE_LIBRADIUS
struct rad_handle;
int isakmp_cfg_radius_common(struct rad_handle *, int);
#endif
#ifdef HAVE_LIBPAM
int isakmp_cfg_accounting_pam(int, int);
void cleanup_pam(int);
#endif

View File

@ -0,0 +1,353 @@
/* $Id: isakmp_frag.c,v 1.1.1.1 2005/02/12 11:12:20 manu Exp $ */
/*
* Copyright (C) 2004 Emmanuel Dreyfus
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#include "config.h"
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/queue.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <openssl/md5.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#if TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# if HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
# endif
#endif
#include <netdb.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <ctype.h>
#include "var.h"
#include "misc.h"
#include "vmbuf.h"
#include "plog.h"
#include "sockmisc.h"
#include "schedule.h"
#include "debug.h"
#include "isakmp_var.h"
#include "isakmp.h"
#include "handler.h"
#include "isakmp_frag.h"
#include "strnames.h"
int
isakmp_sendfrags(iph1, buf)
struct ph1handle *iph1;
vchar_t *buf;
{
struct isakmp *hdr;
struct isakmp_frag *fraghdr;
caddr_t data;
caddr_t sdata;
size_t datalen;
size_t max_datalen;
size_t fraglen;
vchar_t *frag;
unsigned int trailer;
unsigned int fragnum = 0;
size_t len;
int etype;
/*
* Catch the exchange type for later: the fragments and the
* fragmented packet must have the same exchange type.
*/
hdr = (struct isakmp *)buf->v;
etype = hdr->etype;
/*
* We want to send a a packet smaller than ISAKMP_FRAG_MAXLEN
* First compute the maximum data length that will fit in it
*/
max_datalen = ISAKMP_FRAG_MAXLEN -
(sizeof(*hdr) + sizeof(*fraghdr) + sizeof(trailer));
sdata = buf->v;
len = buf->l;
while (len > 0) {
fragnum++;
if (len > max_datalen)
datalen = max_datalen;
else
datalen = len;
fraglen = sizeof(*hdr)
+ sizeof(*fraghdr)
+ datalen;
if ((frag = vmalloc(fraglen)) == NULL) {
plog(LLV_ERROR, LOCATION, NULL,
"Cannot allocate memory\n");
return -1;
}
set_isakmp_header1(frag, iph1, ISAKMP_NPTYPE_FRAG);
hdr = (struct isakmp *)frag->v;
hdr->etype = etype;
fraghdr = (struct isakmp_frag *)(hdr + 1);
fraghdr->unknown0 = htons(0);
fraghdr->len = htons(fraglen - sizeof(*hdr));
fraghdr->unknown1 = htons(1);
fraghdr->index = fragnum;
if (len == datalen)
fraghdr->flags = ISAKMP_FRAG_LAST;
else
fraghdr->flags = 0;
data = (caddr_t)(fraghdr + 1);
memcpy(data, sdata, datalen);
if (isakmp_send(iph1, frag) < 0) {
plog(LLV_ERROR, LOCATION, NULL, "isakmp_send failed\n");
return -1;
}
vfree(frag);
len -= datalen;
sdata += datalen;
}
return fragnum;
}
unsigned int
vendorid_frag_cap(gen)
struct isakmp_gen *gen;
{
int *hp;
hp = (int *)(gen + 1);
return ntohl(hp[MD5_DIGEST_LENGTH / sizeof(*hp)]);
}
int
isakmp_frag_extract(iph1, msg)
struct ph1handle *iph1;
vchar_t *msg;
{
struct isakmp *isakmp;
struct isakmp_frag *frag;
struct isakmp_frag_item *item;
vchar_t *buf;
size_t len;
int last_frag = 0;
char *data;
int i;
if (msg->l < sizeof(*isakmp) + sizeof(*frag)) {
plog(LLV_ERROR, LOCATION, NULL, "Message too short\n");
return -1;
}
isakmp = (struct isakmp *)msg->v;
frag = (struct isakmp_frag *)(isakmp + 1);
/*
* frag->len is the frag payload data plus the frag payload header,
* whose size is sizeof(*frag)
*/
if (msg->l < sizeof(*isakmp) + ntohs(frag->len)) {
plog(LLV_ERROR, LOCATION, NULL, "Fragment too short\n");
return -1;
}
if ((buf = vmalloc(ntohs(frag->len) - sizeof(*frag))) == NULL) {
plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
return -1;
}
if ((item = racoon_malloc(sizeof(*item))) == NULL) {
plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
vfree(buf);
return -1;
}
data = (char *)(frag + 1);
memcpy(buf->v, data, buf->l);
item->frag_num = frag->index;
item->frag_last = (frag->flags & ISAKMP_FRAG_LAST);
item->frag_next = NULL;
item->frag_packet = buf;
/* Look for the last frag while inserting the new item in the chain */
if (item->frag_last)
last_frag = item->frag_num;
if (iph1->frag_chain == NULL) {
iph1->frag_chain = item;
} else {
struct isakmp_frag_item *current;
current = iph1->frag_chain;
while (current->frag_next) {
if (current->frag_last)
last_frag = item->frag_num;
current = current->frag_next;
}
current->frag_next = item;
}
/* If we saw the last frag, check if the chain is complete */
if (last_frag != 0) {
for (i = 1; i <= last_frag; i++) {
item = iph1->frag_chain;
do {
if (item->frag_num == i)
break;
item = item->frag_next;
} while (item != NULL);
if (item == NULL) /* Not found */
break;
}
if (item != NULL) /* It is complete */
return 1;
}
return 0;
}
vchar_t *
isakmp_frag_reassembly(iph1)
struct ph1handle *iph1;
{
struct isakmp_frag_item *item;
size_t len = 0;
vchar_t *buf = NULL;
int frag_count = 0;
int i;
char *data;
if ((item = iph1->frag_chain) == NULL) {
plog(LLV_ERROR, LOCATION, NULL, "No fragment to reassemble\n");
goto out;
}
do {
frag_count++;
len += item->frag_packet->l;
item = item->frag_next;
} while (item != NULL);
if ((buf = vmalloc(len)) == NULL) {
plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
goto out;
}
data = buf->v;
for (i = 1; i <= frag_count; i++) {
item = iph1->frag_chain;
do {
if (item->frag_num == i)
break;
item = item->frag_next;
} while (item != NULL);
if (item == NULL) {
plog(LLV_ERROR, LOCATION, NULL,
"Missing fragment #%d\n", i);
vfree(buf);
buf = NULL;
goto out;
}
memcpy(data, item->frag_packet->v, item->frag_packet->l);
data += item->frag_packet->l;
}
out:
item = iph1->frag_chain;
do {
struct isakmp_frag_item *next_item;
next_item = item->frag_next;
vfree(item->frag_packet);
racoon_free(item);
item = next_item;
} while (item != NULL);
iph1->frag_chain = NULL;
return buf;
}
vchar_t *
isakmp_frag_addcap(buf, cap)
vchar_t *buf;
int cap;
{
int *capp;
size_t len;
/* If the capability has not been added, add room now */
len = buf->l;
if (len == MD5_DIGEST_LENGTH) {
if ((buf = vrealloc(buf, len + sizeof(cap))) == NULL) {
plog(LLV_ERROR, LOCATION, NULL,
"Cannot allocate memory\n");
return NULL;
}
capp = (int *)(buf->v + len);
*capp = htonl(0);
}
capp = (int *)(buf->v + MD5_DIGEST_LENGTH);
*capp |= htonl(cap);
return buf;
}

View File

@ -0,0 +1,49 @@
/* $Id: isakmp_frag.h,v 1.1.1.1 2005/02/12 11:12:20 manu Exp $ */
/*
* Copyright (C) 2004 Emmanuel Dreyfus
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
/* IKE fragmentation capabilities */
#define VENDORID_FRAG_BASE 0x40000000
#define VENDORID_FRAG_AGG 0x80000000
#define ISAKMP_FRAG_MAXLEN 552
struct isakmp_frag_item {
int frag_num;
int frag_last;
struct isakmp_frag_item *frag_next;
vchar_t *frag_packet;
};
int isakmp_sendfrags(struct ph1handle *, vchar_t *);
unsigned int vendorid_frag_cap(struct isakmp_gen *);
int isakmp_frag_extract(struct ph1handle *, vchar_t *);
vchar_t *isakmp_frag_reassembly(struct ph1handle *);
vchar_t *isakmp_frag_addcap(vchar_t *, int);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,50 @@
/* $Id: isakmp_ident.h,v 1.1.1.1 2005/02/12 11:12:23 manu Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#ifndef _ISAKMP_IDENT_H
#define _ISAKMP_IDENT_H
extern int ident_i1send __P((struct ph1handle *, vchar_t *));
extern int ident_i2recv __P((struct ph1handle *, vchar_t *));
extern int ident_i2send __P((struct ph1handle *, vchar_t *));
extern int ident_i3recv __P((struct ph1handle *, vchar_t *));
extern int ident_i3send __P((struct ph1handle *, vchar_t *));
extern int ident_i4recv __P((struct ph1handle *, vchar_t *));
extern int ident_i4send __P((struct ph1handle *, vchar_t *));
extern int ident_r1recv __P((struct ph1handle *, vchar_t *));
extern int ident_r1send __P((struct ph1handle *, vchar_t *));
extern int ident_r2recv __P((struct ph1handle *, vchar_t *));
extern int ident_r2send __P((struct ph1handle *, vchar_t *));
extern int ident_r3recv __P((struct ph1handle *, vchar_t *));
extern int ident_r3send __P((struct ph1handle *, vchar_t *));
#endif /* _ISAKMP_IDENT_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,55 @@
/* $Id: isakmp_inf.h,v 1.1.1.1 2005/02/12 11:12:27 manu Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* 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.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``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 PROJECT OR CONTRIBUTORS 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.
*/
#ifndef _ISAKMP_INF_H
#define _ISAKMP_INF_H
struct saproto;
extern int isakmp_info_recv __P((struct ph1handle *, vchar_t *));
extern int isakmp_info_send_d1 __P((struct ph1handle *));
extern int isakmp_info_send_d2 __P((struct ph2handle *));
extern int isakmp_info_send_nx __P((struct isakmp *,
struct sockaddr *, struct sockaddr *, int, vchar_t *));
extern int isakmp_info_send_n1 __P((struct ph1handle *, int, vchar_t *));
extern int isakmp_info_send_n2 __P((struct ph2handle *, int, vchar_t *));
extern int isakmp_info_send_common __P((struct ph1handle *,
vchar_t *, u_int32_t, int));
extern vchar_t * isakmp_add_pl_n __P((vchar_t *, u_int8_t **, int,
struct saproto *, vchar_t *));
extern void isakmp_check_notify __P((struct isakmp_gen *, struct ph1handle *));
#ifdef ENABLE_DPD
extern int isakmp_sched_r_u __P((struct ph1handle *, int));
#endif
#endif /* _ISAKMP_INF_H */

Some files were not shown because too many files have changed in this diff Show More