This commit is contained in:
@@ -0,0 +1,220 @@
|
||||
# Doxyfile 1.4.1-KDevelop
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Project related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
PROJECT_NAME = "charon"
|
||||
PROJECT_NUMBER = 1.0
|
||||
OUTPUT_DIRECTORY = doc/api
|
||||
CREATE_SUBDIRS = NO
|
||||
OUTPUT_LANGUAGE = English
|
||||
USE_WINDOWS_ENCODING = NO
|
||||
BRIEF_MEMBER_DESC = YES
|
||||
REPEAT_BRIEF = YES
|
||||
ABBREVIATE_BRIEF =
|
||||
ALWAYS_DETAILED_SEC = NO
|
||||
INLINE_INHERITED_MEMB = NO
|
||||
FULL_PATH_NAMES = YES
|
||||
STRIP_FROM_PATH =
|
||||
STRIP_FROM_INC_PATH =
|
||||
SHORT_NAMES = NO
|
||||
JAVADOC_AUTOBRIEF = YES
|
||||
MULTILINE_CPP_IS_BRIEF = NO
|
||||
DETAILS_AT_TOP = YES
|
||||
INHERIT_DOCS = YES
|
||||
DISTRIBUTE_GROUP_DOC = NO
|
||||
TAB_SIZE = 1
|
||||
ALIASES =
|
||||
OPTIMIZE_OUTPUT_FOR_C = NO
|
||||
OPTIMIZE_OUTPUT_JAVA = NO
|
||||
SUBGROUPING = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Build related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
EXTRACT_ALL = NO
|
||||
EXTRACT_PRIVATE = NO
|
||||
EXTRACT_STATIC = NO
|
||||
EXTRACT_LOCAL_CLASSES = NO
|
||||
EXTRACT_LOCAL_METHODS = NO
|
||||
HIDE_UNDOC_MEMBERS = NO
|
||||
HIDE_UNDOC_CLASSES = NO
|
||||
HIDE_FRIEND_COMPOUNDS = NO
|
||||
HIDE_IN_BODY_DOCS = NO
|
||||
INTERNAL_DOCS = NO
|
||||
CASE_SENSE_NAMES = YES
|
||||
HIDE_SCOPE_NAMES = NO
|
||||
SHOW_INCLUDE_FILES = YES
|
||||
INLINE_INFO = YES
|
||||
SORT_MEMBER_DOCS = YES
|
||||
SORT_BRIEF_DOCS = NO
|
||||
SORT_BY_SCOPE_NAME = NO
|
||||
GENERATE_TODOLIST = YES
|
||||
GENERATE_TESTLIST = NO
|
||||
GENERATE_BUGLIST = YES
|
||||
GENERATE_DEPRECATEDLIST = YES
|
||||
ENABLED_SECTIONS =
|
||||
MAX_INITIALIZER_LINES = 30
|
||||
SHOW_USED_FILES = YES
|
||||
SHOW_DIRECTORIES = NO
|
||||
FILE_VERSION_FILTER =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to warning and progress messages
|
||||
#---------------------------------------------------------------------------
|
||||
QUIET = NO
|
||||
WARNINGS = YES
|
||||
WARN_IF_UNDOCUMENTED = YES
|
||||
WARN_IF_DOC_ERROR = YES
|
||||
WARN_NO_PARAMDOC = NO
|
||||
WARN_FORMAT = "$file:$line: $text"
|
||||
WARN_LOGFILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the input files
|
||||
#---------------------------------------------------------------------------
|
||||
INPUT = ./
|
||||
FILE_PATTERNS = *.h *.txt
|
||||
RECURSIVE = YES
|
||||
EXCLUDE =
|
||||
EXCLUDE_SYMLINKS = NO
|
||||
EXCLUDE_PATTERNS =
|
||||
EXAMPLE_PATH =
|
||||
EXAMPLE_PATTERNS =
|
||||
EXAMPLE_RECURSIVE = NO
|
||||
IMAGE_PATH =
|
||||
INPUT_FILTER =
|
||||
FILTER_PATTERNS =
|
||||
FILTER_SOURCE_FILES = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to source browsing
|
||||
#---------------------------------------------------------------------------
|
||||
SOURCE_BROWSER = NO
|
||||
INLINE_SOURCES = NO
|
||||
STRIP_CODE_COMMENTS = NO
|
||||
REFERENCED_BY_RELATION = NO
|
||||
REFERENCES_RELATION = NO
|
||||
VERBATIM_HEADERS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the alphabetical class index
|
||||
#---------------------------------------------------------------------------
|
||||
ALPHABETICAL_INDEX = NO
|
||||
COLS_IN_ALPHA_INDEX = 5
|
||||
IGNORE_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the HTML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_HTML = YES
|
||||
HTML_OUTPUT = .
|
||||
HTML_FILE_EXTENSION = .html
|
||||
HTML_HEADER =
|
||||
HTML_FOOTER =
|
||||
HTML_STYLESHEET =
|
||||
HTML_ALIGN_MEMBERS = YES
|
||||
GENERATE_HTMLHELP = NO
|
||||
CHM_FILE =
|
||||
HHC_LOCATION =
|
||||
GENERATE_CHI = NO
|
||||
BINARY_TOC = NO
|
||||
TOC_EXPAND = NO
|
||||
DISABLE_INDEX = YES
|
||||
ENUM_VALUES_PER_LINE = 1
|
||||
GENERATE_TREEVIEW = YES
|
||||
TREEVIEW_WIDTH = 250
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the LaTeX output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_LATEX = NO
|
||||
LATEX_OUTPUT = latex
|
||||
LATEX_CMD_NAME = latex
|
||||
MAKEINDEX_CMD_NAME = makeindex
|
||||
COMPACT_LATEX = NO
|
||||
PAPER_TYPE = a4wide
|
||||
EXTRA_PACKAGES =
|
||||
LATEX_HEADER =
|
||||
PDF_HYPERLINKS = NO
|
||||
USE_PDFLATEX = NO
|
||||
LATEX_BATCHMODE = NO
|
||||
LATEX_HIDE_INDICES = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the RTF output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_RTF = NO
|
||||
RTF_OUTPUT = rtf
|
||||
COMPACT_RTF = NO
|
||||
RTF_HYPERLINKS = NO
|
||||
RTF_STYLESHEET_FILE =
|
||||
RTF_EXTENSIONS_FILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the man page output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_MAN = NO
|
||||
MAN_OUTPUT = man
|
||||
MAN_EXTENSION = .3
|
||||
MAN_LINKS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the XML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_XML = NO
|
||||
XML_OUTPUT = xml
|
||||
XML_SCHEMA =
|
||||
XML_DTD =
|
||||
XML_PROGRAMLISTING = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options for the AutoGen Definitions output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_AUTOGEN_DEF = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the Perl module output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_PERLMOD = NO
|
||||
PERLMOD_LATEX = NO
|
||||
PERLMOD_PRETTY = YES
|
||||
PERLMOD_MAKEVAR_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the preprocessor
|
||||
#---------------------------------------------------------------------------
|
||||
ENABLE_PREPROCESSING = YES
|
||||
MACRO_EXPANSION = YES
|
||||
EXPAND_ONLY_PREDEF = NO
|
||||
SEARCH_INCLUDES = YES
|
||||
INCLUDE_PATH =
|
||||
INCLUDE_FILE_PATTERNS =
|
||||
PREDEFINED = LEAK_DETECTIVE
|
||||
EXPAND_AS_DEFINED =
|
||||
SKIP_FUNCTION_MACROS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::additions related to external references
|
||||
#---------------------------------------------------------------------------
|
||||
TAGFILES =
|
||||
GENERATE_TAGFILE =
|
||||
ALLEXTERNALS = NO
|
||||
EXTERNAL_GROUPS = YES
|
||||
PERL_PATH = /usr/bin/perl
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the dot tool
|
||||
#---------------------------------------------------------------------------
|
||||
CLASS_DIAGRAMS = YES
|
||||
HIDE_UNDOC_RELATIONS = YES
|
||||
HAVE_DOT = NO
|
||||
CLASS_GRAPH = YES
|
||||
COLLABORATION_GRAPH = YES
|
||||
GROUP_GRAPHS = YES
|
||||
UML_LOOK = NO
|
||||
TEMPLATE_RELATIONS = NO
|
||||
INCLUDE_GRAPH = YES
|
||||
INCLUDED_BY_GRAPH = YES
|
||||
CALL_GRAPH = NO
|
||||
GRAPHICAL_HIERARCHY = YES
|
||||
DIRECTORY_GRAPH = YES
|
||||
DOT_IMAGE_FORMAT = png
|
||||
DOT_PATH =
|
||||
DOTFILE_DIRS =
|
||||
MAX_DOT_GRAPH_WIDTH = 1024
|
||||
MAX_DOT_GRAPH_HEIGHT = 1024
|
||||
MAX_DOT_GRAPH_DEPTH = 0
|
||||
DOT_TRANSPARENT = NO
|
||||
DOT_MULTI_TARGETS = NO
|
||||
GENERATE_LEGEND = YES
|
||||
DOT_CLEANUP = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::additions related to the search engine
|
||||
#---------------------------------------------------------------------------
|
||||
SEARCHENGINE = NO
|
||||
@@ -0,0 +1,99 @@
|
||||
# Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
# Hochschule fuer Technik Rapperswil
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the
|
||||
# Free Software Foundation; either version 2 of the License, or (at your
|
||||
# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# for more details.
|
||||
#
|
||||
|
||||
FREESWANSRCDIR=../..
|
||||
# include strongswan Makefile, if charon sits in its tree
|
||||
ifeq ($(shell ls $(FREESWANSRCDIR)/Makefile.inc 2>&1), ../../Makefile.inc)
|
||||
include ${FREESWANSRCDIR}/Makefile.inc
|
||||
else
|
||||
# Defaults if not using strongswan defines
|
||||
USE_LEAK_DETECTIVE?=false
|
||||
INSTALL=install
|
||||
INSTBINFLAGS=-b --suffix=.old
|
||||
LIBEXECDIR=/usr/local/libexec/ipsec
|
||||
SHAREDLIBDIR=/usr/local/lib
|
||||
endif
|
||||
|
||||
|
||||
BUILD_DIR= ./bin/
|
||||
|
||||
BINNAMECHARON= $(BUILD_DIR)charon
|
||||
BINNAMESTROKE= $(BUILD_DIR)stroke
|
||||
BINNAMETEST= $(BUILD_DIR)run_tests
|
||||
BINNAMELIB= $(BUILD_DIR)libstrongswan.so
|
||||
|
||||
MAIN_DIR= ./
|
||||
|
||||
CFLAGS= -Icharon -Ilib -Istroke -fPIC -Wall -g
|
||||
ifeq ($(USE_LEAK_DETECTIVE),true)
|
||||
CFLAGS+= -DLEAK_DETECTIVE
|
||||
endif
|
||||
|
||||
# objects is extended by each included Makefile
|
||||
CHARON_OBJS=
|
||||
LIB_OBJS=
|
||||
TEST_OBJS=
|
||||
|
||||
all : programs
|
||||
|
||||
include $(MAIN_DIR)charon/Makefile.charon
|
||||
include $(MAIN_DIR)lib/Makefile.lib
|
||||
include $(MAIN_DIR)stroke/Makefile.stroke
|
||||
include $(MAIN_DIR)testing/Makefile.testcases
|
||||
|
||||
programs : $(BINNAMECHARON) $(BINNAMESTROKE)
|
||||
|
||||
test : $(BINNAMETEST)
|
||||
LD_LIBRARY_PATH=$(BUILD_DIR) $(BINNAMETEST)
|
||||
|
||||
run : $(BINNAMECHARON)
|
||||
LD_LIBRARY_PATH=$(BUILD_DIR) $(BINNAMECHARON)
|
||||
|
||||
apidoc :
|
||||
doxygen Doxyfile
|
||||
|
||||
build_dir:
|
||||
mkdir -p $(BUILD_DIR)
|
||||
|
||||
$(BINNAMELIB) : build_dir $(LIB_OBJS)
|
||||
$(CC) -lpthread -ldl -lgmp -shared $(LIB_OBJS) -o $@
|
||||
|
||||
$(BINNAMECHARON) : build_dir $(CHARON_OBJS) $(BINNAMELIB) $(BUILD_DIR)daemon.o
|
||||
$(CC) -L./bin -lstrongswan $(CHARON_OBJS) $(BUILD_DIR)daemon.o -o $@
|
||||
|
||||
$(BINNAMETEST) : build_dir $(CHARON_OBJS) $(TEST_OBJS) $(BINNAMELIB) $(BUILD_DIR)testcases.o
|
||||
$(CC) -L./bin -lstrongswan $(LDFLAGS) $(CHARON_OBJS) $(TEST_OBJS) $(BUILD_DIR)testcases.o -o $@
|
||||
|
||||
$(BINNAMESTROKE) : build_dir $(BINNAMELIB) $(BUILD_DIR)stroke.o
|
||||
$(CC) $(LDFLAGS) $(CFLAGS) $(BUILD_DIR)stroke.o -o $@
|
||||
|
||||
install : $(BINNAMECHARON) $(BINNAMESTROKE)
|
||||
$(INSTALL) $(INSTBINFLAGS) $(BINNAMECHARON) $(BINNAMESTROKE) $(LIBEXECDIR)
|
||||
$(INSTALL) $(INSTBINFLAGS) $(BINNAMELIB) $(SHAREDLIBDIR)
|
||||
|
||||
install_file_list:
|
||||
@echo $(LIBEXECDIR)/charon
|
||||
@echo $(LIBEXECDIR)/stroke
|
||||
@echo $(SHAREDLIBDIR)/libstrongswan.so
|
||||
|
||||
clean :
|
||||
rm -fR $(BUILD_DIR)
|
||||
|
||||
cleanall: clean
|
||||
|
||||
distclean: clean
|
||||
|
||||
mostlyclean: clean
|
||||
|
||||
realclean: clean
|
||||
@@ -0,0 +1,105 @@
|
||||
<?xml version = '1.0'?>
|
||||
<kdevelop>
|
||||
<general>
|
||||
<author>Martin Willi</author>
|
||||
<email>[email protected]</email>
|
||||
<version>$VERSION$</version>
|
||||
<projectmanagement>KDevCustomProject</projectmanagement>
|
||||
<primarylanguage>C</primarylanguage>
|
||||
<ignoreparts/>
|
||||
</general>
|
||||
<kdevcustomproject>
|
||||
<run>
|
||||
<mainprogram>Source</mainprogram>
|
||||
<directoryradio>executable</directoryradio>
|
||||
</run>
|
||||
<general>
|
||||
<activedir/>
|
||||
</general>
|
||||
</kdevcustomproject>
|
||||
<kdevdebugger>
|
||||
<general>
|
||||
<dbgshell/>
|
||||
</general>
|
||||
</kdevdebugger>
|
||||
<kdevdoctreeview>
|
||||
<ignoretocs>
|
||||
<toc>ada</toc>
|
||||
<toc>ada_bugs_gcc</toc>
|
||||
<toc>bash</toc>
|
||||
<toc>bash_bugs</toc>
|
||||
<toc>clanlib</toc>
|
||||
<toc>fortran_bugs_gcc</toc>
|
||||
<toc>gnome1</toc>
|
||||
<toc>gnustep</toc>
|
||||
<toc>gtk</toc>
|
||||
<toc>gtk_bugs</toc>
|
||||
<toc>haskell</toc>
|
||||
<toc>haskell_bugs_ghc</toc>
|
||||
<toc>java_bugs_gcc</toc>
|
||||
<toc>java_bugs_sun</toc>
|
||||
<toc>kde2book</toc>
|
||||
<toc>libstdc++</toc>
|
||||
<toc>opengl</toc>
|
||||
<toc>pascal_bugs_fp</toc>
|
||||
<toc>php</toc>
|
||||
<toc>php_bugs</toc>
|
||||
<toc>perl</toc>
|
||||
<toc>perl_bugs</toc>
|
||||
<toc>python</toc>
|
||||
<toc>python_bugs</toc>
|
||||
<toc>qt-kdev3</toc>
|
||||
<toc>ruby</toc>
|
||||
<toc>ruby_bugs</toc>
|
||||
<toc>sdl</toc>
|
||||
<toc>stl</toc>
|
||||
<toc>sw</toc>
|
||||
<toc>w3c-dom-level2-html</toc>
|
||||
<toc>w3c-svg</toc>
|
||||
<toc>w3c-uaag10</toc>
|
||||
<toc>wxwidgets_bugs</toc>
|
||||
</ignoretocs>
|
||||
<ignoreqt_xml>
|
||||
<toc>Guide to the Qt Translation Tools</toc>
|
||||
<toc>Qt Assistant Manual</toc>
|
||||
<toc>Qt Designer Manual</toc>
|
||||
<toc>Qt Reference Documentation</toc>
|
||||
<toc>qmake User Guide</toc>
|
||||
</ignoreqt_xml>
|
||||
<ignoredoxygen>
|
||||
<toc>KDE Libraries (Doxygen)</toc>
|
||||
</ignoredoxygen>
|
||||
</kdevdoctreeview>
|
||||
<kdevfilecreate>
|
||||
<filetypes/>
|
||||
<useglobaltypes>
|
||||
<type ext="c" />
|
||||
<type ext="h" />
|
||||
</useglobaltypes>
|
||||
</kdevfilecreate>
|
||||
<kdevcppsupport>
|
||||
<references/>
|
||||
<codecompletion>
|
||||
<includeGlobalFunctions>true</includeGlobalFunctions>
|
||||
<includeTypes>true</includeTypes>
|
||||
<includeEnums>true</includeEnums>
|
||||
<includeTypedefs>false</includeTypedefs>
|
||||
<automaticCodeCompletion>true</automaticCodeCompletion>
|
||||
<automaticArgumentsHint>true</automaticArgumentsHint>
|
||||
<automaticHeaderCompletion>true</automaticHeaderCompletion>
|
||||
<codeCompletionDelay>250</codeCompletionDelay>
|
||||
<argumentsHintDelay>400</argumentsHintDelay>
|
||||
<headerCompletionDelay>250</headerCompletionDelay>
|
||||
</codecompletion>
|
||||
</kdevcppsupport>
|
||||
<kdevfileview>
|
||||
<groups>
|
||||
<hidenonprojectfiles>false</hidenonprojectfiles>
|
||||
<hidenonlocation>false</hidenonlocation>
|
||||
</groups>
|
||||
<tree>
|
||||
<hidepatterns>*.o,*.lo,CVS</hidepatterns>
|
||||
<hidenonprojectfiles>false</hidenonprojectfiles>
|
||||
</tree>
|
||||
</kdevfileview>
|
||||
</kdevelop>
|
||||
@@ -0,0 +1,25 @@
|
||||
# Copyright (C) 2006 Martin Willi
|
||||
# Hochschule fuer Technik Rapperswil
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the
|
||||
# Free Software Foundation; either version 2 of the License, or (at your
|
||||
# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# for more details.
|
||||
#
|
||||
CHARON_DIR= $(MAIN_DIR)charon/
|
||||
|
||||
$(BUILD_DIR)daemon.o : $(CHARON_DIR)daemon.c $(CHARON_DIR)daemon.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
|
||||
include $(CHARON_DIR)network/Makefile.network
|
||||
include $(CHARON_DIR)config/Makefile.config
|
||||
include $(CHARON_DIR)encoding/Makefile.encoding
|
||||
include $(CHARON_DIR)queues/Makefile.queues
|
||||
include $(CHARON_DIR)sa/Makefile.sa
|
||||
include $(CHARON_DIR)threads/Makefile.threads
|
||||
@@ -0,0 +1,32 @@
|
||||
# Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
# Hochschule fuer Technik Rapperswil
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the
|
||||
# Free Software Foundation; either version 2 of the License, or (at your
|
||||
# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# for more details.
|
||||
#
|
||||
|
||||
CONFIG_DIR= $(CHARON_DIR)config/
|
||||
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)traffic_selector.o
|
||||
$(BUILD_DIR)traffic_selector.o : $(CONFIG_DIR)traffic_selector.c $(CONFIG_DIR)traffic_selector.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)proposal.o
|
||||
$(BUILD_DIR)proposal.o : $(CONFIG_DIR)proposal.c $(CONFIG_DIR)proposal.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)configuration.o
|
||||
$(BUILD_DIR)configuration.o : $(CONFIG_DIR)configuration.c $(CONFIG_DIR)configuration.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
include $(CONFIG_DIR)connections/Makefile.connections
|
||||
include $(CONFIG_DIR)credentials/Makefile.credentials
|
||||
include $(CONFIG_DIR)policies/Makefile.policies
|
||||
Executable
+112
@@ -0,0 +1,112 @@
|
||||
/**
|
||||
* @file configuration.c
|
||||
*
|
||||
* @brief Implementation of configuration_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "configuration.h"
|
||||
|
||||
#include <types.h>
|
||||
|
||||
/**
|
||||
* First retransmit timeout in milliseconds.
|
||||
* Timeout value is increasing in each retransmit round.
|
||||
*/
|
||||
#define RETRANSMIT_TIMEOUT 3000
|
||||
|
||||
/**
|
||||
* Timeout in milliseconds after that a half open IKE_SA gets deleted.
|
||||
*/
|
||||
#define HALF_OPEN_IKE_SA_TIMEOUT 30000
|
||||
|
||||
/**
|
||||
* Max retransmit count.
|
||||
* 0 for infinite. The max time a half open IKE_SA is alive is set by
|
||||
* RETRANSMIT_TIMEOUT.
|
||||
*/
|
||||
#define MAX_RETRANSMIT_COUNT 0
|
||||
|
||||
|
||||
typedef struct private_configuration_t private_configuration_t;
|
||||
|
||||
/**
|
||||
* Private data of an configuration_t object.
|
||||
*/
|
||||
struct private_configuration_t {
|
||||
|
||||
/**
|
||||
* Public part of configuration_t object.
|
||||
*/
|
||||
configuration_t public;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Implementation of configuration_t.get_retransmit_timeout.
|
||||
*/
|
||||
static status_t get_retransmit_timeout (private_configuration_t *this, u_int32_t retransmit_count, u_int32_t *timeout)
|
||||
{
|
||||
int new_timeout = RETRANSMIT_TIMEOUT, i;
|
||||
if (retransmit_count > MAX_RETRANSMIT_COUNT && MAX_RETRANSMIT_COUNT != 0)
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
for (i = 0; i < retransmit_count; i++)
|
||||
{
|
||||
new_timeout *= 2;
|
||||
}
|
||||
|
||||
*timeout = new_timeout;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of configuration_t.get_half_open_ike_sa_timeout.
|
||||
*/
|
||||
static u_int32_t get_half_open_ike_sa_timeout (private_configuration_t *this)
|
||||
{
|
||||
return HALF_OPEN_IKE_SA_TIMEOUT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of configuration_t.destroy.
|
||||
*/
|
||||
static void destroy(private_configuration_t *this)
|
||||
{
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header-file
|
||||
*/
|
||||
configuration_t *configuration_create()
|
||||
{
|
||||
private_configuration_t *this = malloc_thing(private_configuration_t);
|
||||
|
||||
/* public functions */
|
||||
this->public.destroy = (void(*)(configuration_t*))destroy;
|
||||
this->public.get_retransmit_timeout = (status_t (*) (configuration_t *, u_int32_t retransmit_count, u_int32_t *timeout))get_retransmit_timeout;
|
||||
this->public.get_half_open_ike_sa_timeout = (u_int32_t (*) (configuration_t *)) get_half_open_ike_sa_timeout;
|
||||
|
||||
return (&this->public);
|
||||
}
|
||||
Executable
+89
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
* @file configuration.h
|
||||
*
|
||||
* @brief Interface configuration_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef CONFIGURATION_H_
|
||||
#define CONFIGURATION_H_
|
||||
|
||||
#include <types.h>
|
||||
|
||||
|
||||
typedef struct configuration_t configuration_t;
|
||||
|
||||
/**
|
||||
* @brief The interface for various daemon related configs.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - configuration_create()
|
||||
*
|
||||
* @ingroup config
|
||||
*/
|
||||
struct configuration_t {
|
||||
|
||||
/**
|
||||
* @brief Returns the retransmit timeout.
|
||||
*
|
||||
* The timeout values are managed by the configuration, so
|
||||
* another backoff algorithm may be implemented here.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param retransmit_count number of times a message was retransmitted so far
|
||||
* @param[out] timeout the new retransmit timeout in milliseconds
|
||||
*
|
||||
* @return
|
||||
* - FAILED, if the message should not be retransmitted
|
||||
* - SUCCESS
|
||||
*/
|
||||
status_t (*get_retransmit_timeout) (configuration_t *this, u_int32_t retransmit_count, u_int32_t *timeout);
|
||||
|
||||
/**
|
||||
* @brief Returns the timeout for an half open IKE_SA in ms.
|
||||
*
|
||||
* Half open means that the IKE_SA is still in one of the following states:
|
||||
* - INITIATOR_INIT
|
||||
* - RESPONDER_INIT
|
||||
* - IKE_SA_INIT_REQUESTED
|
||||
* - IKE_SA_INIT_RESPONDED
|
||||
* - IKE_AUTH_REQUESTED
|
||||
*
|
||||
* @param this calling object
|
||||
* @return timeout in milliseconds (ms)
|
||||
*/
|
||||
u_int32_t (*get_half_open_ike_sa_timeout) (configuration_t *this);
|
||||
|
||||
/**
|
||||
* @brief Destroys a configuration_t object.
|
||||
*
|
||||
* @param this calling object
|
||||
*/
|
||||
void (*destroy) (configuration_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Creates a configuration backend.
|
||||
*
|
||||
* @return static_configuration_t object
|
||||
*
|
||||
* @ingroup config
|
||||
*/
|
||||
configuration_t *configuration_create();
|
||||
|
||||
#endif /*CONFIGURATION_H_*/
|
||||
@@ -0,0 +1,24 @@
|
||||
# Copyright (C) 2006 Martin Willi
|
||||
# Hochschule fuer Technik Rapperswil
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the
|
||||
# Free Software Foundation; either version 2 of the License, or (at your
|
||||
# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# for more details.
|
||||
#
|
||||
|
||||
CONNECTIONS_DIR= $(CONFIG_DIR)connections/
|
||||
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)connection.o
|
||||
$(BUILD_DIR)connection.o : $(CONNECTIONS_DIR)connection.c $(CONNECTIONS_DIR)connection.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)local_connection_store.o
|
||||
$(BUILD_DIR)local_connection_store.o : $(CONNECTIONS_DIR)local_connection_store.c $(CONNECTIONS_DIR)local_connection_store.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
@@ -0,0 +1,367 @@
|
||||
/**
|
||||
* @file connection.c
|
||||
*
|
||||
* @brief Implementation of connection_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "connection.h"
|
||||
|
||||
#include <utils/linked_list.h>
|
||||
#include <utils/logger.h>
|
||||
|
||||
/**
|
||||
* String mappings for auth_method_t.
|
||||
*/
|
||||
mapping_t auth_method_m[] = {
|
||||
{RSA_DIGITAL_SIGNATURE, "RSA"},
|
||||
{SHARED_KEY_MESSAGE_INTEGRITY_CODE, "SHARED_KEY"},
|
||||
{DSS_DIGITAL_SIGNATURE, "DSS"},
|
||||
{MAPPING_END, NULL}
|
||||
};
|
||||
|
||||
|
||||
typedef struct private_connection_t private_connection_t;
|
||||
|
||||
/**
|
||||
* Private data of an connection_t object
|
||||
*/
|
||||
struct private_connection_t {
|
||||
|
||||
/**
|
||||
* Public part
|
||||
*/
|
||||
connection_t public;
|
||||
|
||||
/**
|
||||
* Name of the connection
|
||||
*/
|
||||
char *name;
|
||||
|
||||
/**
|
||||
* ID of us
|
||||
*/
|
||||
identification_t *my_id;
|
||||
|
||||
/**
|
||||
* ID of remote peer
|
||||
*/
|
||||
identification_t *other_id;
|
||||
|
||||
/**
|
||||
* Host information of my host.
|
||||
*/
|
||||
host_t *my_host;
|
||||
|
||||
/**
|
||||
* Host information of other host.
|
||||
*/
|
||||
host_t *other_host;
|
||||
|
||||
/**
|
||||
* Method to use for own authentication data
|
||||
*/
|
||||
auth_method_t auth_method;
|
||||
|
||||
/**
|
||||
* Supported proposals
|
||||
*/
|
||||
linked_list_t *proposals;
|
||||
};
|
||||
|
||||
/**
|
||||
* Implementation of connection_t.get_name.
|
||||
*/
|
||||
static char *get_name (private_connection_t *this)
|
||||
{
|
||||
return this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of connection_t.get_my_id.
|
||||
*/
|
||||
static identification_t *get_my_id (private_connection_t *this)
|
||||
{
|
||||
return this->my_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of connection_t.get_other_id.
|
||||
*/
|
||||
static identification_t *get_other_id(private_connection_t *this)
|
||||
{
|
||||
return this->other_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of connection_t.update_my_id
|
||||
*/
|
||||
static void update_my_id(private_connection_t *this, identification_t *my_id)
|
||||
{
|
||||
this->my_id->destroy(this->my_id);
|
||||
this->my_id = my_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of connection_t.update_other_id
|
||||
*/
|
||||
static void update_other_id(private_connection_t *this, identification_t *other_id)
|
||||
{
|
||||
this->other_id->destroy(this->other_id);
|
||||
this->other_id = other_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of connection_t.get_my_host.
|
||||
*/
|
||||
static host_t * get_my_host (private_connection_t *this)
|
||||
{
|
||||
return this->my_host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of connection_t.update_my_host.
|
||||
*/
|
||||
static void update_my_host(private_connection_t *this, host_t *my_host)
|
||||
{
|
||||
this->my_host->destroy(this->my_host);
|
||||
this->my_host = my_host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of connection_t.update_other_host.
|
||||
*/
|
||||
static void update_other_host(private_connection_t *this, host_t *other_host)
|
||||
{
|
||||
this->other_host->destroy(this->other_host);
|
||||
this->other_host = other_host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of connection_t.get_other_host.
|
||||
*/
|
||||
static host_t * get_other_host (private_connection_t *this)
|
||||
{
|
||||
return this->other_host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of connection_t.get_proposals.
|
||||
*/
|
||||
static linked_list_t* get_proposals (private_connection_t *this)
|
||||
{
|
||||
return this->proposals;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of connection_t.select_proposal.
|
||||
*/
|
||||
static proposal_t *select_proposal(private_connection_t *this, linked_list_t *proposals)
|
||||
{
|
||||
iterator_t *stored_iter, *supplied_iter;
|
||||
proposal_t *stored, *supplied, *selected;
|
||||
|
||||
stored_iter = this->proposals->create_iterator(this->proposals, TRUE);
|
||||
supplied_iter = proposals->create_iterator(proposals, TRUE);
|
||||
|
||||
/* compare all stored proposals with all supplied. Stored ones are preferred. */
|
||||
while (stored_iter->has_next(stored_iter))
|
||||
{
|
||||
supplied_iter->reset(supplied_iter);
|
||||
stored_iter->current(stored_iter, (void**)&stored);
|
||||
|
||||
while (supplied_iter->has_next(supplied_iter))
|
||||
{
|
||||
supplied_iter->current(supplied_iter, (void**)&supplied);
|
||||
selected = stored->select(stored, supplied);
|
||||
if (selected)
|
||||
{
|
||||
/* they match, return */
|
||||
stored_iter->destroy(stored_iter);
|
||||
supplied_iter->destroy(supplied_iter);
|
||||
return selected;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* no proposal match :-(, will result in a NO_PROPOSAL_CHOSEN... */
|
||||
stored_iter->destroy(stored_iter);
|
||||
supplied_iter->destroy(supplied_iter);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of connection_t.add_proposal.
|
||||
*/
|
||||
static void add_proposal (private_connection_t *this, proposal_t *proposal)
|
||||
{
|
||||
this->proposals->insert_last(this->proposals, proposal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of connection_t.auth_method_t.
|
||||
*/
|
||||
static auth_method_t get_auth_method(private_connection_t *this)
|
||||
{
|
||||
return this->auth_method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of connection_t.get_dh_group.
|
||||
*/
|
||||
static diffie_hellman_group_t get_dh_group(private_connection_t *this)
|
||||
{
|
||||
iterator_t *iterator;
|
||||
proposal_t *proposal;
|
||||
algorithm_t *algo;
|
||||
|
||||
iterator = this->proposals->create_iterator(this->proposals, TRUE);
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
iterator->current(iterator, (void**)&proposal);
|
||||
proposal->get_algorithm(proposal, PROTO_IKE, DIFFIE_HELLMAN_GROUP, &algo);
|
||||
if (algo)
|
||||
{
|
||||
iterator->destroy(iterator);
|
||||
return algo->algorithm;
|
||||
}
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
return MODP_UNDEFINED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of connection_t.check_dh_group.
|
||||
*/
|
||||
static bool check_dh_group(private_connection_t *this, diffie_hellman_group_t dh_group)
|
||||
{
|
||||
iterator_t *prop_iter, *alg_iter;
|
||||
proposal_t *proposal;
|
||||
algorithm_t *algo;
|
||||
|
||||
prop_iter = this->proposals->create_iterator(this->proposals, TRUE);
|
||||
while (prop_iter->has_next(prop_iter))
|
||||
{
|
||||
prop_iter->current(prop_iter, (void**)&proposal);
|
||||
alg_iter = proposal->create_algorithm_iterator(proposal, PROTO_IKE, DIFFIE_HELLMAN_GROUP);
|
||||
while (alg_iter->has_next(alg_iter))
|
||||
{
|
||||
alg_iter->current(alg_iter, (void**)&algo);
|
||||
if (algo->algorithm == dh_group)
|
||||
{
|
||||
prop_iter->destroy(prop_iter);
|
||||
alg_iter->destroy(alg_iter);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
prop_iter->destroy(prop_iter);
|
||||
alg_iter->destroy(alg_iter);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of connection_t.clone.
|
||||
*/
|
||||
static connection_t *clone(private_connection_t *this)
|
||||
{
|
||||
iterator_t *iterator;
|
||||
proposal_t *proposal;
|
||||
private_connection_t *clone = (private_connection_t*)connection_create(
|
||||
this->name,
|
||||
this->my_host->clone(this->my_host),
|
||||
this->other_host->clone(this->other_host),
|
||||
this->my_id->clone(this->my_id),
|
||||
this->other_id->clone(this->other_id),
|
||||
this->auth_method);
|
||||
|
||||
/* clone all proposals */
|
||||
iterator = this->proposals->create_iterator(this->proposals, TRUE);
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
iterator->current(iterator, (void**)&proposal);
|
||||
proposal = proposal->clone(proposal);
|
||||
clone->proposals->insert_last(clone->proposals, (void*)proposal);
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
return &clone->public;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of connection_t.destroy.
|
||||
*/
|
||||
static void destroy (private_connection_t *this)
|
||||
{
|
||||
proposal_t *proposal;
|
||||
|
||||
while (this->proposals->remove_last(this->proposals, (void**)&proposal) == SUCCESS)
|
||||
{
|
||||
proposal->destroy(proposal);
|
||||
}
|
||||
this->proposals->destroy(this->proposals);
|
||||
|
||||
this->my_host->destroy(this->my_host);
|
||||
this->other_host->destroy(this->other_host);
|
||||
this->my_id->destroy(this->my_id);
|
||||
this->other_id->destroy(this->other_id);
|
||||
free(this->name);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
connection_t * connection_create(char *name, host_t *my_host, host_t *other_host, identification_t *my_id, identification_t *other_id, auth_method_t auth_method)
|
||||
{
|
||||
private_connection_t *this = malloc_thing(private_connection_t);
|
||||
|
||||
/* public functions */
|
||||
this->public.get_name = (char*(*)(connection_t*))get_name;
|
||||
this->public.get_my_id = (identification_t*(*)(connection_t*))get_my_id;
|
||||
this->public.get_other_id = (identification_t*(*)(connection_t*))get_other_id;
|
||||
this->public.get_my_host = (host_t*(*)(connection_t*))get_my_host;
|
||||
this->public.update_my_host = (void(*)(connection_t*,host_t*))update_my_host;
|
||||
this->public.update_other_host = (void(*)(connection_t*,host_t*))update_other_host;
|
||||
this->public.update_my_id = (void(*)(connection_t*,identification_t*))update_my_id;
|
||||
this->public.update_other_id = (void(*)(connection_t*,identification_t*))update_other_id;
|
||||
this->public.get_other_host = (host_t*(*)(connection_t*))get_other_host;
|
||||
this->public.get_proposals = (linked_list_t*(*)(connection_t*))get_proposals;
|
||||
this->public.select_proposal = (proposal_t*(*)(connection_t*,linked_list_t*))select_proposal;
|
||||
this->public.add_proposal = (void(*)(connection_t*, proposal_t*)) add_proposal;
|
||||
this->public.get_auth_method = (auth_method_t(*)(connection_t*)) get_auth_method;
|
||||
this->public.get_dh_group = (diffie_hellman_group_t(*)(connection_t*)) get_dh_group;
|
||||
this->public.check_dh_group = (bool(*)(connection_t*,diffie_hellman_group_t)) check_dh_group;
|
||||
this->public.clone = (connection_t*(*)(connection_t*))clone;
|
||||
this->public.destroy = (void(*)(connection_t*))destroy;
|
||||
|
||||
/* private variables */
|
||||
this->name = strdup(name);
|
||||
this->my_host = my_host;
|
||||
this->other_host = other_host;
|
||||
this->my_id = my_id;
|
||||
this->other_id = other_id;
|
||||
this->auth_method = auth_method;
|
||||
|
||||
this->proposals = linked_list_create();
|
||||
|
||||
return (&this->public);
|
||||
}
|
||||
@@ -0,0 +1,283 @@
|
||||
/**
|
||||
* @file connection.h
|
||||
*
|
||||
* @brief Interface of connection_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef CONNECTION_H_
|
||||
#define CONNECTION_H_
|
||||
|
||||
#include <types.h>
|
||||
#include <utils/host.h>
|
||||
#include <utils/linked_list.h>
|
||||
#include <utils/identification.h>
|
||||
#include <config/proposal.h>
|
||||
#include <crypto/diffie_hellman.h>
|
||||
|
||||
|
||||
typedef enum auth_method_t auth_method_t;
|
||||
|
||||
/**
|
||||
* AUTH Method to use.
|
||||
*
|
||||
* @ingroup config
|
||||
*/
|
||||
enum auth_method_t {
|
||||
/**
|
||||
* Computed as specified in section 2.15 of RFC using
|
||||
* an RSA private key over a PKCS#1 padded hash.
|
||||
*/
|
||||
RSA_DIGITAL_SIGNATURE = 1,
|
||||
|
||||
/**
|
||||
* Computed as specified in section 2.15 of RFC using the
|
||||
* shared key associated with the identity in the ID payload
|
||||
* and the negotiated prf function
|
||||
*/
|
||||
SHARED_KEY_MESSAGE_INTEGRITY_CODE = 2,
|
||||
|
||||
/**
|
||||
* Computed as specified in section 2.15 of RFC using a
|
||||
* DSS private key over a SHA-1 hash.
|
||||
*/
|
||||
DSS_DIGITAL_SIGNATURE = 3,
|
||||
};
|
||||
|
||||
/**
|
||||
* string mappings for auth method.
|
||||
*
|
||||
* @ingroup config
|
||||
*/
|
||||
extern mapping_t auth_method_m[];
|
||||
|
||||
|
||||
typedef struct connection_t connection_t;
|
||||
|
||||
/**
|
||||
* @brief A connection_t defines the rules to set up an IKE_SA.
|
||||
*
|
||||
*
|
||||
* @b Constructors:
|
||||
* - connection_create()
|
||||
*
|
||||
* @ingroup config
|
||||
*/
|
||||
struct connection_t {
|
||||
|
||||
/**
|
||||
* @brief Get my ID for this connection.
|
||||
*
|
||||
* Object is NOT getting cloned.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return host information as identification_t object
|
||||
*/
|
||||
identification_t *(*get_my_id) (connection_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get others ID for this connection.
|
||||
*
|
||||
* Object is NOT getting cloned.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return host information as identification_t object
|
||||
*/
|
||||
identification_t *(*get_other_id) (connection_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get my address as host_t object.
|
||||
*
|
||||
* Object is NOT getting cloned.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return host information as host_t object
|
||||
*/
|
||||
host_t *(*get_my_host) (connection_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get others address as host_t object.
|
||||
*
|
||||
* Object is NOT getting cloned.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return host information as host_t object
|
||||
*/
|
||||
host_t *(*get_other_host) (connection_t *this);
|
||||
|
||||
/**
|
||||
* @brief Update address of my host.
|
||||
*
|
||||
* It may be necessary to uptdate own address, as it
|
||||
* is set to the default route (0.0.0.0) in some cases.
|
||||
* Old host is destroyed, new one NOT cloned.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param my_host new host to set as my_host
|
||||
*/
|
||||
void (*update_my_host) (connection_t *this, host_t *my_host);
|
||||
|
||||
/**
|
||||
* @brief Update address of remote host.
|
||||
*
|
||||
* It may be necessary to uptdate remote address, as a
|
||||
* connection may define %any (0.0.0.0) or a subnet.
|
||||
* Old host is destroyed, new one NOT cloned.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param my_host new host to set as other_host
|
||||
*/
|
||||
void (*update_other_host) (connection_t *this, host_t *other_host);
|
||||
|
||||
/**
|
||||
* @brief Update own ID.
|
||||
*
|
||||
* It may be necessary to uptdate own ID, as it
|
||||
* is set to %any or to e.g. *@strongswan.org in
|
||||
* some cases.
|
||||
* Old ID is destroyed, new one NOT cloned.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param my_id new ID to set as my_id
|
||||
*/
|
||||
void (*update_my_id) (connection_t *this, identification_t *my_id);
|
||||
|
||||
/**
|
||||
* @brief Update others ID.
|
||||
*
|
||||
* It may be necessary to uptdate others ID, as it
|
||||
* is set to %any or to e.g. *@strongswan.org in
|
||||
* some cases.
|
||||
* Old ID is destroyed, new one NOT cloned.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param other_id new ID to set as other_id
|
||||
*/
|
||||
void (*update_other_id) (connection_t *this, identification_t *other_id);
|
||||
|
||||
/**
|
||||
* @brief Returns a list of all supported proposals.
|
||||
*
|
||||
* Returned list is still owned by connection and MUST NOT
|
||||
* modified or destroyed.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return list containing all the proposals
|
||||
*/
|
||||
linked_list_t *(*get_proposals) (connection_t *this);
|
||||
|
||||
/**
|
||||
* @brief Adds a proposal to the list.
|
||||
*
|
||||
* The first added proposal has the highest priority, the last
|
||||
* added the lowest.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param proposal proposal to add
|
||||
*/
|
||||
void (*add_proposal) (connection_t *this, proposal_t *proposal);
|
||||
|
||||
/**
|
||||
* @brief Select a proposed from suggested proposals.
|
||||
*
|
||||
* Returned proposal must be destroyed after usage.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param proposals list of proposals to select from
|
||||
* @return selected proposal, or NULL if none matches.
|
||||
*/
|
||||
proposal_t *(*select_proposal) (connection_t *this, linked_list_t *proposals);
|
||||
|
||||
/**
|
||||
* @brief Get the authentication method to use
|
||||
*
|
||||
* @param this calling object
|
||||
* @return authentication method
|
||||
*/
|
||||
auth_method_t (*get_auth_method) (connection_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get the connection name.
|
||||
*
|
||||
* Name must not be freed, since it points to
|
||||
* internal data.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return name of the connection
|
||||
*/
|
||||
char* (*get_name) (connection_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get the DH group to use for connection initialization.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return dh group to use for initialization
|
||||
*/
|
||||
diffie_hellman_group_t (*get_dh_group) (connection_t *this);
|
||||
|
||||
/**
|
||||
* @brief Check if a suggested dh group is acceptable.
|
||||
*
|
||||
* If we guess a wrong DH group for IKE_SA_INIT, the other
|
||||
* peer will send us a offer. But is this acceptable for us?
|
||||
*
|
||||
* @param this calling object
|
||||
* @return TRUE if group acceptable
|
||||
*/
|
||||
bool (*check_dh_group) (connection_t *this, diffie_hellman_group_t dh_group);
|
||||
|
||||
/**
|
||||
* @brief Clone a connection_t object.
|
||||
*
|
||||
* @param this connection to clone
|
||||
* @return clone of it
|
||||
*/
|
||||
connection_t *(*clone) (connection_t *this);
|
||||
|
||||
/**
|
||||
* @brief Destroys a connection_t object.
|
||||
*
|
||||
* @param this calling object
|
||||
*/
|
||||
void (*destroy) (connection_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Creates a connection_t object.
|
||||
*
|
||||
* Supplied hosts/IDs become owned by connection, so
|
||||
* do not modify or destroy them after a call to
|
||||
* connection_create(). Name gets cloned internally.
|
||||
*
|
||||
* @param name connection identifier
|
||||
* @param my_host host_t representing local address
|
||||
* @param other_host host_t representing remote address
|
||||
* @param my_id identification_t for me
|
||||
* @param other_id identification_t for other
|
||||
* @param auth_method Authentication method to use for our(!) auth data
|
||||
* @return connection_t object.
|
||||
*
|
||||
* @ingroup config
|
||||
*/
|
||||
connection_t * connection_create(char *name,
|
||||
host_t *my_host, host_t *other_host,
|
||||
identification_t *my_id,
|
||||
identification_t *other_id,
|
||||
auth_method_t auth_method);
|
||||
|
||||
#endif /* CONNECTION_H_ */
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
/**
|
||||
* @file connection_store.h
|
||||
*
|
||||
* @brief Interface connection_store_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef CONNECTION_STORE_H_
|
||||
#define CONNECTION_STORE_H_
|
||||
|
||||
#include <types.h>
|
||||
#include <config/connections/connection.h>
|
||||
|
||||
|
||||
typedef struct connection_store_t connection_store_t;
|
||||
|
||||
/**
|
||||
* @brief The interface for a store of connection_t's.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - stroke_create()
|
||||
*
|
||||
* @ingroup config
|
||||
*/
|
||||
struct connection_store_t {
|
||||
|
||||
/**
|
||||
* @brief Returns a connection definition identified by two IDs.
|
||||
*
|
||||
* This call is useful to get a connection which is identified by IDs
|
||||
* rather than addresses, e.g. for connection setup on user request.
|
||||
* The returned connection gets created/cloned and therefore must
|
||||
* be destroyed after usage.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param my_id own ID of connection
|
||||
* @param other_id others ID of connection
|
||||
* @return
|
||||
* - connection_t, if found
|
||||
* - NULL otherwise
|
||||
*/
|
||||
connection_t *(*get_connection_by_ids) (connection_store_t *this, identification_t *my_id, identification_t *other_id);
|
||||
|
||||
/**
|
||||
* @brief Returns a connection definition identified by two hosts.
|
||||
*
|
||||
* This call is usefull to get a connection identified by addresses.
|
||||
* It may be used after kernel request for traffic protection.
|
||||
* The returned connection gets created/cloned and therefore must
|
||||
* be destroyed after usage.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param my_id own address of connection
|
||||
* @param other_id others address of connection
|
||||
* @return
|
||||
* - connection_t, if found
|
||||
* - NULL otherwise
|
||||
*/
|
||||
connection_t *(*get_connection_by_hosts) (connection_store_t *this, host_t *my_host, host_t *other_host);
|
||||
|
||||
/**
|
||||
* @brief Returns a connection identified by its name.
|
||||
*
|
||||
* This call is usefull to get a connection identified its
|
||||
* name, as on an connection setup.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param name name of the connection to get
|
||||
* @return
|
||||
* - connection_t, if found
|
||||
* - NULL otherwise
|
||||
*/
|
||||
connection_t *(*get_connection_by_name) (connection_store_t *this, char *name);
|
||||
|
||||
/**
|
||||
* @brief Add a connection to the store.
|
||||
*
|
||||
* After a successful call, the connection is owned by the store and may
|
||||
* not be manipulated nor destroyed.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param connection connection to add
|
||||
* @return
|
||||
* - SUCCESS, or
|
||||
* - FAILED
|
||||
*/
|
||||
status_t (*add_connection) (connection_store_t *this, connection_t *connection);
|
||||
|
||||
/**
|
||||
* @brief Destroys a connection_store_t object.
|
||||
*
|
||||
* @param this calling object
|
||||
*/
|
||||
void (*destroy) (connection_store_t *this);
|
||||
};
|
||||
|
||||
#endif /* CONNECTION_STORE_H_ */
|
||||
@@ -0,0 +1,228 @@
|
||||
/**
|
||||
* @file local_connection_store.c
|
||||
*
|
||||
* @brief Implementation of local_connection_store_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "local_connection_store.h"
|
||||
|
||||
#include <utils/linked_list.h>
|
||||
#include <utils/logger_manager.h>
|
||||
|
||||
|
||||
typedef struct private_local_connection_store_t private_local_connection_store_t;
|
||||
|
||||
/**
|
||||
* Private data of an local_connection_store_t object
|
||||
*/
|
||||
struct private_local_connection_store_t {
|
||||
|
||||
/**
|
||||
* Public part
|
||||
*/
|
||||
local_connection_store_t public;
|
||||
|
||||
/**
|
||||
* stored connection
|
||||
*/
|
||||
linked_list_t *connections;
|
||||
|
||||
/**
|
||||
* Assigned logger
|
||||
*/
|
||||
logger_t *logger;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of connection_store_t.get_connection_by_hosts.
|
||||
*/
|
||||
static connection_t *get_connection_by_hosts(private_local_connection_store_t *this, host_t *my_host, host_t *other_host)
|
||||
{
|
||||
iterator_t *iterator;
|
||||
connection_t *current, *found = NULL;
|
||||
|
||||
this->logger->log(this->logger, CONTROL|LEVEL1, "getting config for hosts %s - %s",
|
||||
my_host->get_address(my_host), other_host->get_address(other_host));
|
||||
|
||||
iterator = this->connections->create_iterator(this->connections, TRUE);
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
host_t *config_my_host, *config_other_host;
|
||||
|
||||
iterator->current(iterator, (void**)¤t);
|
||||
|
||||
config_my_host = current->get_my_host(current);
|
||||
config_other_host = current->get_other_host(current);
|
||||
|
||||
/* first check if ip is equal */
|
||||
if(config_other_host->ip_equals(config_other_host, other_host))
|
||||
{
|
||||
this->logger->log(this->logger, CONTROL|LEVEL2, "config entry with remote host %s",
|
||||
config_other_host->get_address(config_other_host));
|
||||
/* could be right one, check my_host for default route*/
|
||||
if (config_my_host->is_default_route(config_my_host))
|
||||
{
|
||||
found = current->clone(current);
|
||||
break;
|
||||
}
|
||||
/* check now if host informations are the same */
|
||||
else if (config_my_host->ip_equals(config_my_host,my_host))
|
||||
{
|
||||
found = current->clone(current);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
/* Then check for wildcard hosts!
|
||||
* TODO
|
||||
* actually its only checked if other host with default route can be found! */
|
||||
else if (config_other_host->is_default_route(config_other_host))
|
||||
{
|
||||
/* could be right one, check my_host for default route*/
|
||||
if (config_my_host->is_default_route(config_my_host))
|
||||
{
|
||||
found = current->clone(current);
|
||||
break;
|
||||
}
|
||||
/* check now if host informations are the same */
|
||||
else if (config_my_host->ip_equals(config_my_host,my_host))
|
||||
{
|
||||
found = current->clone(current);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
/* apply hosts as they are supplied since my_host may be %defaultroute, and other_host may be %any. */
|
||||
if (found)
|
||||
{
|
||||
found->update_my_host(found, my_host->clone(my_host));
|
||||
found->update_other_host(found, other_host->clone(other_host));
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of connection_store_t.get_connection_by_ids.
|
||||
*/
|
||||
static connection_t *get_connection_by_ids(private_local_connection_store_t *this, identification_t *my_id, identification_t *other_id)
|
||||
{
|
||||
iterator_t *iterator;
|
||||
connection_t *current, *found = NULL;
|
||||
|
||||
this->logger->log(this->logger, CONTROL|LEVEL1, "getting config for ids %s - %s",
|
||||
my_id->get_string(my_id), other_id->get_string(other_id));
|
||||
|
||||
iterator = this->connections->create_iterator(this->connections, TRUE);
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
identification_t *config_my_id, *config_other_id;
|
||||
|
||||
iterator->current(iterator, (void**)¤t);
|
||||
|
||||
config_my_id = current->get_my_id(current);
|
||||
config_other_id = current->get_other_id(current);
|
||||
|
||||
/* first check if ids are equal
|
||||
* TODO: Add wildcard checks */
|
||||
if (config_other_id->equals(config_other_id, other_id) &&
|
||||
config_my_id->equals(config_my_id, my_id))
|
||||
{
|
||||
this->logger->log(this->logger, CONTROL|LEVEL2, "config entry with remote id %s",
|
||||
config_other_id->get_string(config_other_id));
|
||||
found = current->clone(current);
|
||||
break;
|
||||
}
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of connection_store_t.get_connection_by_name.
|
||||
*/
|
||||
static connection_t *get_connection_by_name(private_local_connection_store_t *this, char *name)
|
||||
{
|
||||
iterator_t *iterator;
|
||||
connection_t *current, *found = NULL;
|
||||
|
||||
iterator = this->connections->create_iterator(this->connections, TRUE);
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
iterator->current(iterator, (void**)¤t);
|
||||
if (strcmp(name, current->get_name(current)) == 0)
|
||||
{
|
||||
found = current->clone(current);
|
||||
break;
|
||||
}
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of connection_store_t.add_connection.
|
||||
*/
|
||||
static status_t add_connection(private_local_connection_store_t *this, connection_t *connection)
|
||||
{
|
||||
this->connections->insert_last(this->connections, connection);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of connection_store_t.destroy.
|
||||
*/
|
||||
static void destroy (private_local_connection_store_t *this)
|
||||
{
|
||||
connection_t *connection;
|
||||
|
||||
while (this->connections->remove_last(this->connections, (void**)&connection) == SUCCESS)
|
||||
{
|
||||
connection->destroy(connection);
|
||||
}
|
||||
this->connections->destroy(this->connections);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
local_connection_store_t * local_connection_store_create()
|
||||
{
|
||||
private_local_connection_store_t *this = malloc_thing(private_local_connection_store_t);
|
||||
|
||||
this->public.connection_store.get_connection_by_hosts = (connection_t*(*)(connection_store_t*,host_t*,host_t*))get_connection_by_hosts;
|
||||
this->public.connection_store.get_connection_by_ids = (connection_t*(*)(connection_store_t*,identification_t*,identification_t*))get_connection_by_ids;
|
||||
this->public.connection_store.get_connection_by_name = (connection_t*(*)(connection_store_t*,char*))get_connection_by_name;
|
||||
this->public.connection_store.add_connection = (status_t(*)(connection_store_t*,connection_t*))add_connection;
|
||||
this->public.connection_store.destroy = (void(*)(connection_store_t*))destroy;
|
||||
|
||||
/* private variables */
|
||||
this->connections = linked_list_create();
|
||||
this->logger = logger_manager->get_logger(logger_manager, CONFIG);
|
||||
|
||||
return (&this->public);
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* @file local_connection_store.h
|
||||
*
|
||||
* @brief Interface of local_connection_store_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef LOCAL_CONNECTION_H_
|
||||
#define LOCAL_CONNECTION_H_
|
||||
|
||||
#include <types.h>
|
||||
#include <config/connections/connection_store.h>
|
||||
|
||||
|
||||
typedef struct local_connection_store_t local_connection_store_t;
|
||||
|
||||
/**
|
||||
* @brief A connection_store_t implementation using a simple connection list.
|
||||
*
|
||||
* The local_connection_store_t class implements the connection_store_t interface
|
||||
* as simple as possible. connection_t's are stored in an in-memory list.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - local_connection_store_create()
|
||||
*
|
||||
* @todo Make thread-save first
|
||||
* @todo Add remove_connection method
|
||||
*
|
||||
* @ingroup config
|
||||
*/
|
||||
struct local_connection_store_t {
|
||||
|
||||
/**
|
||||
* Implements connection_store_t interface
|
||||
*/
|
||||
connection_store_t connection_store;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Creates a local_connection_store_t instance.
|
||||
*
|
||||
* @return connection store instance.
|
||||
*
|
||||
* @ingroup config
|
||||
*/
|
||||
local_connection_store_t * local_connection_store_create();
|
||||
|
||||
#endif /* LOCAL_CONNECTION_H_ */
|
||||
@@ -0,0 +1,20 @@
|
||||
# Copyright (C) 2006 Martin Willi
|
||||
# Hochschule fuer Technik Rapperswil
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the
|
||||
# Free Software Foundation; either version 2 of the License, or (at your
|
||||
# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# for more details.
|
||||
#
|
||||
|
||||
CREDENTIALS_DIR= $(CONFIG_DIR)credentials/
|
||||
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)local_credential_store.o
|
||||
$(BUILD_DIR)local_credential_store.o : $(CREDENTIALS_DIR)local_credential_store.c $(CREDENTIALS_DIR)local_credential_store.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
/**
|
||||
* @file credential_store.h
|
||||
*
|
||||
* @brief Interface credential_store_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef CREDENTIAL_STORE_H_
|
||||
#define CREDENTIAL_STORE_H_
|
||||
|
||||
#include <types.h>
|
||||
#include <crypto/rsa/rsa_private_key.h>
|
||||
#include <crypto/rsa/rsa_public_key.h>
|
||||
#include <utils/identification.h>
|
||||
|
||||
|
||||
typedef struct credential_store_t credential_store_t;
|
||||
|
||||
/**
|
||||
* @brief The interface for a credential_store backend.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - stroke_create()
|
||||
*
|
||||
* @ingroup config
|
||||
*/
|
||||
struct credential_store_t {
|
||||
|
||||
/**
|
||||
* @brief Returns the preshared secret of a specific ID.
|
||||
*
|
||||
* The returned chunk must be destroyed by the caller after usage.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param identification identification_t object identifiying the secret.
|
||||
* @param[out] preshared_secret the preshared secret will be written there.
|
||||
* @return
|
||||
* - NOT_FOUND if no preshared secrets for specific ID could be found
|
||||
* - SUCCESS
|
||||
*
|
||||
* @todo We should use two IDs to query shared secrets, since we want to use different
|
||||
* keys for different peers...
|
||||
*/
|
||||
status_t (*get_shared_secret) (credential_store_t *this, identification_t *identification, chunk_t *preshared_secret);
|
||||
|
||||
/**
|
||||
* @brief Returns the RSA public key of a specific ID.
|
||||
*
|
||||
* The returned rsa_public_key_t must be destroyed by the caller after usage.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param identification identification_t object identifiying the key.
|
||||
* @return public key, or NULL if not found
|
||||
*/
|
||||
rsa_public_key_t * (*get_rsa_public_key) (credential_store_t *this, identification_t *identification);
|
||||
|
||||
/**
|
||||
* @brief Returns the RSA private key of a specific ID.
|
||||
*
|
||||
* The returned rsa_private_key_t must be destroyed by the caller after usage.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param identification identification_t object identifiying the key
|
||||
* @return private key, or NULL if not found
|
||||
*/
|
||||
rsa_private_key_t *(*get_rsa_private_key) (credential_store_t *this, identification_t *identification);
|
||||
|
||||
/**
|
||||
* @brief Destroys a credential_store_t object.
|
||||
*
|
||||
* @param this calling object
|
||||
*/
|
||||
void (*destroy) (credential_store_t *this);
|
||||
};
|
||||
|
||||
#endif /*CREDENTIAL_STORE_H_*/
|
||||
@@ -0,0 +1,315 @@
|
||||
/**
|
||||
* @file local_credential_store.c
|
||||
*
|
||||
* @brief Implementation of local_credential_store_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include "local_credential_store.h"
|
||||
|
||||
#include <utils/linked_list.h>
|
||||
#include <utils/logger_manager.h>
|
||||
#include <crypto/x509.h>
|
||||
|
||||
|
||||
typedef struct key_entry_t key_entry_t;
|
||||
|
||||
/**
|
||||
* Private key with an associated ID to find it
|
||||
*/
|
||||
struct key_entry_t {
|
||||
|
||||
/**
|
||||
* ID, as added
|
||||
*/
|
||||
identification_t *id;
|
||||
|
||||
/**
|
||||
* Associated rsa private key
|
||||
*/
|
||||
rsa_private_key_t *key;
|
||||
};
|
||||
|
||||
|
||||
typedef struct private_local_credential_store_t private_local_credential_store_t;
|
||||
|
||||
/**
|
||||
* Private data of an local_credential_store_t object
|
||||
*/
|
||||
struct private_local_credential_store_t {
|
||||
|
||||
/**
|
||||
* Public part
|
||||
*/
|
||||
local_credential_store_t public;
|
||||
|
||||
/**
|
||||
* list of key_entry_t's with private keys
|
||||
*/
|
||||
linked_list_t *private_keys;
|
||||
|
||||
/**
|
||||
* list of x509 certificates with public keys
|
||||
*/
|
||||
linked_list_t *certificates;
|
||||
|
||||
/**
|
||||
* Assigned logger
|
||||
*/
|
||||
logger_t *logger;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of credential_store_t.get_shared_secret.
|
||||
*/
|
||||
static status_t get_shared_secret(private_local_credential_store_t *this, identification_t *identification, chunk_t *preshared_secret)
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of credential_store_t.get_rsa_public_key.
|
||||
*/
|
||||
static rsa_public_key_t * get_rsa_public_key(private_local_credential_store_t *this, identification_t *identification)
|
||||
{
|
||||
x509_t *current;
|
||||
rsa_public_key_t *found = NULL;
|
||||
iterator_t *iterator;
|
||||
|
||||
this->logger->log(this->logger, CONTROL|LEVEL2, "Looking for public key for %s",
|
||||
identification->get_string(identification));
|
||||
iterator = this->certificates->create_iterator(this->certificates, TRUE);
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
iterator->current(iterator, (void**)¤t);
|
||||
identification_t *stored = current->get_subject(current);
|
||||
this->logger->log(this->logger, CONTROL|LEVEL2, "there is one for %s",
|
||||
stored->get_string(stored));
|
||||
if (identification->equals(identification, stored))
|
||||
{
|
||||
found = current->get_public_key(current);
|
||||
break;
|
||||
}
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of credential_store_t.get_rsa_private_key.
|
||||
*/
|
||||
static rsa_private_key_t *get_rsa_private_key(private_local_credential_store_t *this, identification_t *identification)
|
||||
{
|
||||
rsa_private_key_t *found = NULL;
|
||||
key_entry_t *current;
|
||||
iterator_t *iterator;
|
||||
|
||||
iterator = this->private_keys->create_iterator(this->private_keys, TRUE);
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
iterator->current(iterator, (void**)¤t);
|
||||
if (identification->equals(identification, current->id))
|
||||
{
|
||||
found = current->key->clone(current->key);
|
||||
break;
|
||||
}
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements local_credential_store_t.load_private_keys
|
||||
*/
|
||||
static void load_certificates(private_local_credential_store_t *this, char *path)
|
||||
{
|
||||
struct dirent* entry;
|
||||
struct stat stb;
|
||||
DIR* dir;
|
||||
x509_t *cert;
|
||||
|
||||
dir = opendir(path);
|
||||
if (dir == NULL) {
|
||||
this->logger->log(this->logger, ERROR, "error opening certificate directory \"%s\"", path);
|
||||
return;
|
||||
}
|
||||
while ((entry = readdir(dir)) != NULL)
|
||||
{
|
||||
char file[256];
|
||||
snprintf(file, sizeof(file), "%s/%s", path, entry->d_name);
|
||||
|
||||
if (stat(file, &stb) == -1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
/* try to parse all regular files */
|
||||
if (stb.st_mode & S_IFREG)
|
||||
{
|
||||
cert = x509_create_from_file(file);
|
||||
if (cert)
|
||||
{
|
||||
this->certificates->insert_last(this->certificates, (void*)cert);
|
||||
this->logger->log(this->logger, CONTROL|LEVEL1, "loaded certificate \"%s\"", file);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->logger->log(this->logger, ERROR, "certificate \"%s\" invalid, skipped", file);
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query the ID for a private key, by doing a lookup in the certificates
|
||||
*/
|
||||
static identification_t *get_id_for_private_key(private_local_credential_store_t *this, rsa_private_key_t *private_key)
|
||||
{
|
||||
iterator_t *iterator;
|
||||
x509_t *cert;
|
||||
identification_t *found = NULL;
|
||||
rsa_public_key_t *public_key;
|
||||
|
||||
this->logger->log(this->logger, CONTROL|LEVEL2, "Getting ID for a private key...");
|
||||
|
||||
iterator = this->certificates->create_iterator(this->certificates, TRUE);
|
||||
while (!found && iterator->has_next(iterator))
|
||||
{
|
||||
iterator->current(iterator, (void**)&cert);
|
||||
public_key = cert->get_public_key(cert);
|
||||
if (public_key)
|
||||
{
|
||||
if (private_key->belongs_to(private_key, public_key))
|
||||
{
|
||||
this->logger->log(this->logger, CONTROL|LEVEL2, "found a match");
|
||||
found = cert->get_subject(cert);
|
||||
found = found->clone(found);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->logger->log(this->logger, CONTROL|LEVEL3, "this one did not match");
|
||||
}
|
||||
public_key->destroy(public_key);
|
||||
}
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements local_credential_store_t.load_private_keys
|
||||
*/
|
||||
static void load_private_keys(private_local_credential_store_t *this, char *path)
|
||||
{
|
||||
struct dirent* entry;
|
||||
struct stat stb;
|
||||
DIR* dir;
|
||||
rsa_private_key_t *key;
|
||||
|
||||
dir = opendir(path);
|
||||
if (dir == NULL) {
|
||||
this->logger->log(this->logger, ERROR, "error opening private key directory \"%s\"", path);
|
||||
return;
|
||||
}
|
||||
while ((entry = readdir(dir)) != NULL)
|
||||
{
|
||||
char file[256];
|
||||
snprintf(file, sizeof(file), "%s/%s", path, entry->d_name);
|
||||
|
||||
if (stat(file, &stb) == -1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
/* try to parse all regular files */
|
||||
if (stb.st_mode & S_IFREG)
|
||||
{
|
||||
key = rsa_private_key_create_from_file(file, NULL);
|
||||
if (key)
|
||||
{
|
||||
key_entry_t *entry;
|
||||
identification_t *id = get_id_for_private_key(this, key);
|
||||
if (!id)
|
||||
{
|
||||
this->logger->log(this->logger, ERROR,
|
||||
"no certificate found for private key \"%s\", skipped", file);
|
||||
key->destroy(key);
|
||||
continue;
|
||||
}
|
||||
entry = malloc_thing(key_entry_t);
|
||||
entry->key = key;
|
||||
entry->id = id;
|
||||
this->private_keys->insert_last(this->private_keys, (void*)entry);
|
||||
this->logger->log(this->logger, CONTROL|LEVEL1, "loaded private key \"%s\"", file);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->logger->log(this->logger, ERROR, "private key \"%s\" invalid, skipped", file);
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of credential_store_t.destroy.
|
||||
*/
|
||||
static void destroy(private_local_credential_store_t *this)
|
||||
{
|
||||
x509_t *certificate;
|
||||
key_entry_t *key_entry;
|
||||
|
||||
while (this->certificates->remove_last(this->certificates, (void**)&certificate) == SUCCESS)
|
||||
{
|
||||
certificate->destroy(certificate);
|
||||
}
|
||||
this->certificates->destroy(this->certificates);
|
||||
while (this->private_keys->remove_last(this->private_keys, (void**)&key_entry) == SUCCESS)
|
||||
{
|
||||
key_entry->id->destroy(key_entry->id);
|
||||
key_entry->key->destroy(key_entry->key);
|
||||
free(key_entry);
|
||||
}
|
||||
this->private_keys->destroy(this->private_keys);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
local_credential_store_t * local_credential_store_create()
|
||||
{
|
||||
private_local_credential_store_t *this = malloc_thing(private_local_credential_store_t);
|
||||
|
||||
this->public.credential_store.get_shared_secret = (status_t(*)(credential_store_t*,identification_t*,chunk_t*))get_shared_secret;
|
||||
this->public.credential_store.get_rsa_private_key = (rsa_private_key_t*(*)(credential_store_t*,identification_t*))get_rsa_private_key;
|
||||
this->public.credential_store.get_rsa_public_key = (rsa_public_key_t*(*)(credential_store_t*,identification_t*))get_rsa_public_key;
|
||||
this->public.load_certificates = (void(*)(local_credential_store_t*,char*))load_certificates;
|
||||
this->public.load_private_keys = (void(*)(local_credential_store_t*,char*))load_private_keys;
|
||||
this->public.credential_store.destroy = (void(*)(credential_store_t*))destroy;
|
||||
|
||||
/* private variables */
|
||||
this->private_keys = linked_list_create();
|
||||
this->certificates = linked_list_create();
|
||||
this->logger = logger_manager->get_logger(logger_manager, CONFIG);
|
||||
|
||||
return (&this->public);
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* @file local_credential_store.h
|
||||
*
|
||||
* @brief Interface of local_credential_store_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef LOCAL_CREDENTIAL_H_
|
||||
#define LOCAL_CREDENTIAL_H_
|
||||
|
||||
#include <types.h>
|
||||
#include <config/credentials/credential_store.h>
|
||||
|
||||
|
||||
typedef struct local_credential_store_t local_credential_store_t;
|
||||
|
||||
/**
|
||||
* @brief A credential_store_t implementation using simple credentail lists.
|
||||
*
|
||||
* The local_credential_store_t class implements the credential_store_t interface
|
||||
* as simple as possible. The credentials are stored in lists, and can be loaded
|
||||
* from folders.
|
||||
* Shared secret are not handled yet, so get_shared_secret always returns NOT_FOUND.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - local_credential_store_create()
|
||||
*
|
||||
* @ingroup config
|
||||
*/
|
||||
struct local_credential_store_t {
|
||||
|
||||
/**
|
||||
* Implements credential_store_t interface
|
||||
*/
|
||||
credential_store_t credential_store;
|
||||
|
||||
/**
|
||||
* @brief Loads trusted certificates from a folder.
|
||||
*
|
||||
* Currently, all keys must be in binary DER format.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param path directory to load certificates from
|
||||
*/
|
||||
void (*load_certificates) (local_credential_store_t *this, char *path);
|
||||
|
||||
/**
|
||||
* @brief Loads RSA private keys from a folder.
|
||||
*
|
||||
* Currently, all keys must be unencrypted in binary DER format. Anything
|
||||
* other gets ignored. Further, a certificate for the specific private
|
||||
* key must already be loaded to get the ID from.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param path directory to load keys from
|
||||
*/
|
||||
void (*load_private_keys) (local_credential_store_t *this, char *path);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Creates a local_credential_store_t instance.
|
||||
*
|
||||
* @return credential store instance.
|
||||
*
|
||||
* @ingroup config
|
||||
*/
|
||||
local_credential_store_t *local_credential_store_create();
|
||||
|
||||
#endif /* LOCAL_CREDENTIAL_H_ */
|
||||
@@ -0,0 +1,24 @@
|
||||
# Copyright (C) 2006 Martin Willi
|
||||
# Hochschule fuer Technik Rapperswil
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the
|
||||
# Free Software Foundation; either version 2 of the License, or (at your
|
||||
# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# for more details.
|
||||
#
|
||||
|
||||
POLICIES_DIR= $(CONFIG_DIR)policies/
|
||||
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)policy.o
|
||||
$(BUILD_DIR)policy.o : $(POLICIES_DIR)policy.c $(POLICIES_DIR)policy.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)local_policy_store.o
|
||||
$(BUILD_DIR)local_policy_store.o : $(POLICIES_DIR)local_policy_store.c $(POLICIES_DIR)local_policy_store.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
@@ -0,0 +1,136 @@
|
||||
/**
|
||||
* @file local_policy_store.c
|
||||
*
|
||||
* @brief Implementation of local_policy_store_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "local_policy_store.h"
|
||||
|
||||
#include <utils/linked_list.h>
|
||||
#include <utils/logger_manager.h>
|
||||
|
||||
|
||||
typedef struct private_local_policy_store_t private_local_policy_store_t;
|
||||
|
||||
/**
|
||||
* Private data of an local_policy_store_t object
|
||||
*/
|
||||
struct private_local_policy_store_t {
|
||||
|
||||
/**
|
||||
* Public part
|
||||
*/
|
||||
local_policy_store_t public;
|
||||
|
||||
/**
|
||||
* list of policy_t's
|
||||
*/
|
||||
linked_list_t *policies;
|
||||
|
||||
/**
|
||||
* Assigned logger
|
||||
*/
|
||||
logger_t *logger;
|
||||
};
|
||||
|
||||
/**
|
||||
* Implementation of policy_store_t.add_policy.
|
||||
*/
|
||||
static void add_policy(private_local_policy_store_t *this, policy_t *policy)
|
||||
{
|
||||
this->policies->insert_last(this->policies, (void*)policy);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of policy_store_t.get_policy.
|
||||
*/
|
||||
static policy_t *get_policy(private_local_policy_store_t *this, identification_t *my_id, identification_t *other_id)
|
||||
{
|
||||
iterator_t *iterator;
|
||||
policy_t *current, *found = NULL;
|
||||
|
||||
this->logger->log(this->logger, CONTROL|LEVEL1, "Looking for policy for IDs %s - %s",
|
||||
my_id ? my_id->get_string(my_id) : "%any",
|
||||
other_id->get_string(other_id));
|
||||
iterator = this->policies->create_iterator(this->policies, TRUE);
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
iterator->current(iterator, (void **)¤t);
|
||||
identification_t *config_my_id = current->get_my_id(current);
|
||||
identification_t *config_other_id = current->get_other_id(current);
|
||||
|
||||
this->logger->log(this->logger, CONTROL|LEVEL2, "Found one for %s - %s",
|
||||
config_my_id->get_string(config_my_id),
|
||||
config_other_id->get_string(config_other_id));
|
||||
|
||||
/* check other host first */
|
||||
if (other_id->belongs_to(other_id, config_other_id))
|
||||
{
|
||||
/* get it if my_id not specified */
|
||||
if (my_id->belongs_to(my_id, config_my_id))
|
||||
{
|
||||
found = current->clone(current);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
/* apply IDs as they are requsted, since they may be configured as %any or such */
|
||||
if (found)
|
||||
{
|
||||
found->update_my_id(found, my_id->clone(my_id));
|
||||
found->update_other_id(found, other_id->clone(other_id));
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of policy_store_t.destroy.
|
||||
*/
|
||||
static void destroy(private_local_policy_store_t *this)
|
||||
{
|
||||
policy_t *policy;
|
||||
|
||||
while (this->policies->remove_last(this->policies, (void**)&policy) == SUCCESS)
|
||||
{
|
||||
policy->destroy(policy);
|
||||
}
|
||||
this->policies->destroy(this->policies);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
local_policy_store_t *local_policy_store_create()
|
||||
{
|
||||
private_local_policy_store_t *this = malloc_thing(private_local_policy_store_t);
|
||||
|
||||
this->public.policy_store.add_policy = (void(*)(policy_store_t*,policy_t*))add_policy;
|
||||
this->public.policy_store.get_policy = (policy_t*(*)(policy_store_t*,identification_t*,identification_t*))get_policy;
|
||||
this->public.policy_store.destroy = (void(*)(policy_store_t*))destroy;
|
||||
|
||||
/* private variables */
|
||||
this->policies = linked_list_create();
|
||||
this->logger = logger_manager->get_logger(logger_manager, CONFIG);
|
||||
|
||||
return (&this->public);
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* @file local_policy_store.h
|
||||
*
|
||||
* @brief Interface of local_policy_store_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef LOCAL_POLICY_STORE_H_
|
||||
#define LOCAL_POLICY_STORE_H_
|
||||
|
||||
#include <types.h>
|
||||
#include <config/policies/policy_store.h>
|
||||
|
||||
|
||||
typedef struct local_policy_store_t local_policy_store_t;
|
||||
|
||||
/**
|
||||
* @brief A policy_store_t implementation using a simple policy lists.
|
||||
*
|
||||
* The local_policy_store_t class implements the policy_store_t interface
|
||||
* as simple as possible. The policies are stored in a in-memory list.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - local_policy_store_create()
|
||||
*
|
||||
* @ingroup config
|
||||
*/
|
||||
struct local_policy_store_t {
|
||||
|
||||
/**
|
||||
* Implements policy_store_t interface
|
||||
*/
|
||||
policy_store_t policy_store;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Creates a local_policy_store_t instance.
|
||||
*
|
||||
* @return policy store instance.
|
||||
*
|
||||
* @ingroup config
|
||||
*/
|
||||
local_policy_store_t *local_policy_store_create();
|
||||
|
||||
#endif /* LOCAL_POLICY_STORE_H_ */
|
||||
@@ -0,0 +1,397 @@
|
||||
/**
|
||||
* @file policy.c
|
||||
*
|
||||
* @brief Implementation of policy_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "policy.h"
|
||||
|
||||
#include <utils/linked_list.h>
|
||||
#include <utils/identification.h>
|
||||
#include <utils/logger.h>
|
||||
|
||||
typedef struct private_policy_t private_policy_t;
|
||||
|
||||
/**
|
||||
* Private data of an policy_t object
|
||||
*/
|
||||
struct private_policy_t {
|
||||
|
||||
/**
|
||||
* Public part
|
||||
*/
|
||||
policy_t public;
|
||||
|
||||
/**
|
||||
* id to use to identify us
|
||||
*/
|
||||
identification_t *my_id;
|
||||
|
||||
/**
|
||||
* allowed id for other
|
||||
*/
|
||||
identification_t *other_id;
|
||||
|
||||
/**
|
||||
* list for all proposals
|
||||
*/
|
||||
linked_list_t *proposals;
|
||||
|
||||
/**
|
||||
* list for traffic selectors for my site
|
||||
*/
|
||||
linked_list_t *my_ts;
|
||||
|
||||
/**
|
||||
* list for traffic selectors for others site
|
||||
*/
|
||||
linked_list_t *other_ts;
|
||||
|
||||
/**
|
||||
* select_traffic_selectors for both
|
||||
*/
|
||||
linked_list_t *(*select_traffic_selectors) (private_policy_t *,linked_list_t*,linked_list_t*);
|
||||
};
|
||||
|
||||
/**
|
||||
* Implementation of policy_t.get_my_id
|
||||
*/
|
||||
static identification_t *get_my_id(private_policy_t *this)
|
||||
{
|
||||
return this->my_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of policy_t.get_other_id
|
||||
*/
|
||||
static identification_t *get_other_id(private_policy_t *this)
|
||||
{
|
||||
return this->other_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of policy_t.update_my_id
|
||||
*/
|
||||
static void update_my_id(private_policy_t *this, identification_t *my_id)
|
||||
{
|
||||
this->my_id->destroy(this->my_id);
|
||||
this->my_id = my_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of policy_t.update_other_id
|
||||
*/
|
||||
static void update_other_id(private_policy_t *this, identification_t *other_id)
|
||||
{
|
||||
this->other_id->destroy(this->other_id);
|
||||
this->other_id = other_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function which does the work for policy_t.update_my_ts and update_other_ts
|
||||
*/
|
||||
static void update_ts(linked_list_t* list, host_t *new_host)
|
||||
{
|
||||
traffic_selector_t *ts;
|
||||
iterator_t *iterator;
|
||||
|
||||
iterator = list->create_iterator(list, TRUE);
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
iterator->current(iterator, (void**)&ts);
|
||||
ts->update_address_range(ts, new_host);
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of policy_t.update_my_id
|
||||
*/
|
||||
static void update_my_ts(private_policy_t *this, host_t *my_host)
|
||||
{
|
||||
update_ts(this->my_ts, my_host);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of policy_t.update_other_ts
|
||||
*/
|
||||
static void update_other_ts(private_policy_t *this, host_t *my_host)
|
||||
{
|
||||
update_ts(this->other_ts, my_host);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of policy_t.get_my_traffic_selectors
|
||||
*/
|
||||
static linked_list_t *get_my_traffic_selectors(private_policy_t *this)
|
||||
{
|
||||
return this->my_ts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of policy_t.get_other_traffic_selectors
|
||||
*/
|
||||
static linked_list_t *get_other_traffic_selectors(private_policy_t *this, traffic_selector_t **traffic_selectors[])
|
||||
{
|
||||
return this->other_ts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of private_policy_t.select_my_traffic_selectors
|
||||
*/
|
||||
static linked_list_t *select_my_traffic_selectors(private_policy_t *this, linked_list_t *supplied)
|
||||
{
|
||||
return this->select_traffic_selectors(this, this->my_ts, supplied);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of private_policy_t.select_other_traffic_selectors
|
||||
*/
|
||||
static linked_list_t *select_other_traffic_selectors(private_policy_t *this, linked_list_t *supplied)
|
||||
{
|
||||
return this->select_traffic_selectors(this, this->other_ts, supplied);
|
||||
}
|
||||
/**
|
||||
* Implementation of private_policy_t.select_traffic_selectors
|
||||
*/
|
||||
static linked_list_t *select_traffic_selectors(private_policy_t *this, linked_list_t *stored, linked_list_t *supplied)
|
||||
{
|
||||
iterator_t *supplied_iter, *stored_iter;
|
||||
traffic_selector_t *supplied_ts, *stored_ts, *selected_ts;
|
||||
linked_list_t *selected = linked_list_create();
|
||||
|
||||
|
||||
stored_iter = stored->create_iterator(stored, TRUE);
|
||||
supplied_iter = supplied->create_iterator(supplied, TRUE);
|
||||
|
||||
/* iterate over all stored selectors */
|
||||
while (stored_iter->has_next(stored_iter))
|
||||
{
|
||||
stored_iter->current(stored_iter, (void**)&stored_ts);
|
||||
|
||||
supplied_iter->reset(supplied_iter);
|
||||
/* iterate over all supplied traffic selectors */
|
||||
while (supplied_iter->has_next(supplied_iter))
|
||||
{
|
||||
supplied_iter->current(supplied_iter, (void**)&supplied_ts);
|
||||
|
||||
selected_ts = stored_ts->get_subset(stored_ts, supplied_ts);
|
||||
if (selected_ts)
|
||||
{
|
||||
/* got a match, add to list */
|
||||
selected->insert_last(selected, (void*)selected_ts);
|
||||
}
|
||||
}
|
||||
}
|
||||
stored_iter->destroy(stored_iter);
|
||||
supplied_iter->destroy(supplied_iter);
|
||||
|
||||
return selected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of policy_t.get_proposal_iterator
|
||||
*/
|
||||
static linked_list_t *get_proposals(private_policy_t *this)
|
||||
{
|
||||
return this->proposals;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of policy_t.select_proposal
|
||||
*/
|
||||
static proposal_t *select_proposal(private_policy_t *this, linked_list_t *proposals)
|
||||
{
|
||||
iterator_t *stored_iter, *supplied_iter;
|
||||
proposal_t *stored, *supplied, *selected;
|
||||
|
||||
stored_iter = this->proposals->create_iterator(this->proposals, TRUE);
|
||||
supplied_iter = proposals->create_iterator(proposals, TRUE);
|
||||
|
||||
/* compare all stored proposals with all supplied. Stored ones are preferred. */
|
||||
while (stored_iter->has_next(stored_iter))
|
||||
{
|
||||
supplied_iter->reset(supplied_iter);
|
||||
stored_iter->current(stored_iter, (void**)&stored);
|
||||
|
||||
while (supplied_iter->has_next(supplied_iter))
|
||||
{
|
||||
supplied_iter->current(supplied_iter, (void**)&supplied);
|
||||
selected = stored->select(stored, supplied);
|
||||
if (selected)
|
||||
{
|
||||
/* they match, return */
|
||||
stored_iter->destroy(stored_iter);
|
||||
supplied_iter->destroy(supplied_iter);
|
||||
return selected;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* no proposal match :-(, will result in a NO_PROPOSAL_CHOSEN... */
|
||||
stored_iter->destroy(stored_iter);
|
||||
supplied_iter->destroy(supplied_iter);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of policy_t.add_my_traffic_selector
|
||||
*/
|
||||
static void add_my_traffic_selector(private_policy_t *this, traffic_selector_t *traffic_selector)
|
||||
{
|
||||
this->my_ts->insert_last(this->my_ts, (void*)traffic_selector);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of policy_t.add_other_traffic_selector
|
||||
*/
|
||||
static void add_other_traffic_selector(private_policy_t *this, traffic_selector_t *traffic_selector)
|
||||
{
|
||||
this->other_ts->insert_last(this->other_ts, (void*)traffic_selector);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of policy_t.add_proposal
|
||||
*/
|
||||
static void add_proposal(private_policy_t *this, proposal_t *proposal)
|
||||
{
|
||||
this->proposals->insert_last(this->proposals, (void*)proposal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements policy_t.destroy.
|
||||
*/
|
||||
static status_t destroy(private_policy_t *this)
|
||||
{
|
||||
proposal_t *proposal;
|
||||
traffic_selector_t *traffic_selector;
|
||||
|
||||
|
||||
/* delete proposals */
|
||||
while(this->proposals->remove_last(this->proposals, (void**)&proposal) == SUCCESS)
|
||||
{
|
||||
proposal->destroy(proposal);
|
||||
}
|
||||
this->proposals->destroy(this->proposals);
|
||||
|
||||
/* delete traffic selectors */
|
||||
while(this->my_ts->remove_last(this->my_ts, (void**)&traffic_selector) == SUCCESS)
|
||||
{
|
||||
traffic_selector->destroy(traffic_selector);
|
||||
}
|
||||
this->my_ts->destroy(this->my_ts);
|
||||
|
||||
/* delete traffic selectors */
|
||||
while(this->other_ts->remove_last(this->other_ts, (void**)&traffic_selector) == SUCCESS)
|
||||
{
|
||||
traffic_selector->destroy(traffic_selector);
|
||||
}
|
||||
this->other_ts->destroy(this->other_ts);
|
||||
|
||||
/* delete ids */
|
||||
this->my_id->destroy(this->my_id);
|
||||
this->other_id->destroy(this->other_id);
|
||||
|
||||
free(this);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements policy_t.clone.
|
||||
*/
|
||||
static policy_t *clone(private_policy_t *this)
|
||||
{
|
||||
private_policy_t *clone = (private_policy_t*)policy_create(this->my_id->clone(this->my_id),
|
||||
this->other_id->clone(this->other_id));
|
||||
iterator_t *iterator;
|
||||
proposal_t *proposal;
|
||||
traffic_selector_t *ts;
|
||||
|
||||
/* clone all proposals */
|
||||
iterator = this->proposals->create_iterator(this->proposals, TRUE);
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
iterator->current(iterator, (void**)&proposal);
|
||||
proposal = proposal->clone(proposal);
|
||||
clone->proposals->insert_last(clone->proposals, (void*)proposal);
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
/* clone all local traffic selectors */
|
||||
iterator = this->my_ts->create_iterator(this->my_ts, TRUE);
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
iterator->current(iterator, (void**)&ts);
|
||||
ts = ts->clone(ts);
|
||||
clone->my_ts->insert_last(clone->my_ts, (void*)ts);
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
/* clone all remote traffic selectors */
|
||||
iterator = this->other_ts->create_iterator(this->other_ts, TRUE);
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
iterator->current(iterator, (void**)&ts);
|
||||
ts = ts->clone(ts);
|
||||
clone->other_ts->insert_last(clone->other_ts, (void*)ts);
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
return &clone->public;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header-file
|
||||
*/
|
||||
policy_t *policy_create(identification_t *my_id, identification_t *other_id)
|
||||
{
|
||||
private_policy_t *this = malloc_thing(private_policy_t);
|
||||
|
||||
/* public functions */
|
||||
this->public.get_my_id = (identification_t*(*)(policy_t*))get_my_id;
|
||||
this->public.get_other_id = (identification_t*(*)(policy_t*))get_other_id;
|
||||
this->public.update_my_id = (void(*)(policy_t*,identification_t*))update_my_id;
|
||||
this->public.update_other_id = (void(*)(policy_t*,identification_t*))update_other_id;
|
||||
this->public.update_my_ts = (void(*)(policy_t*,host_t*))update_my_ts;
|
||||
this->public.update_other_ts = (void(*)(policy_t*,host_t*))update_other_ts;
|
||||
this->public.get_my_traffic_selectors = (linked_list_t*(*)(policy_t*))get_my_traffic_selectors;
|
||||
this->public.select_my_traffic_selectors = (linked_list_t*(*)(policy_t*,linked_list_t*))select_my_traffic_selectors;
|
||||
this->public.get_other_traffic_selectors = (linked_list_t*(*)(policy_t*))get_other_traffic_selectors;
|
||||
this->public.select_other_traffic_selectors = (linked_list_t*(*)(policy_t*,linked_list_t*))select_other_traffic_selectors;
|
||||
this->public.get_proposals = (linked_list_t*(*)(policy_t*))get_proposals;
|
||||
this->public.select_proposal = (proposal_t*(*)(policy_t*,linked_list_t*))select_proposal;
|
||||
this->public.add_my_traffic_selector = (void(*)(policy_t*,traffic_selector_t*))add_my_traffic_selector;
|
||||
this->public.add_other_traffic_selector = (void(*)(policy_t*,traffic_selector_t*))add_other_traffic_selector;
|
||||
this->public.add_proposal = (void(*)(policy_t*,proposal_t*))add_proposal;
|
||||
this->public.clone = (policy_t*(*)(policy_t*))clone;
|
||||
this->public.destroy = (void(*)(policy_t*))destroy;
|
||||
|
||||
/* apply init values */
|
||||
this->my_id = my_id;
|
||||
this->other_id = other_id;
|
||||
|
||||
/* init private members*/
|
||||
this->select_traffic_selectors = select_traffic_selectors;
|
||||
this->proposals = linked_list_create();
|
||||
this->my_ts = linked_list_create();
|
||||
this->other_ts = linked_list_create();
|
||||
|
||||
return (&this->public);
|
||||
}
|
||||
@@ -0,0 +1,249 @@
|
||||
/**
|
||||
* @file policy.h
|
||||
*
|
||||
* @brief Interface of policy_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef POLICY_H_
|
||||
#define POLICY_H_
|
||||
|
||||
#include <types.h>
|
||||
#include <utils/identification.h>
|
||||
#include <config/traffic_selector.h>
|
||||
#include <config/proposal.h>
|
||||
#include <encoding/payloads/auth_payload.h>
|
||||
|
||||
|
||||
typedef struct policy_t policy_t;
|
||||
|
||||
/**
|
||||
* @brief A policy_t defines the policies to apply to CHILD_SAs.
|
||||
*
|
||||
* The given two IDs identify a policy. These rules define how
|
||||
* child SAs may be set up and which traffic may be IPsec'ed.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - policy_create()
|
||||
*
|
||||
* @ingroup config
|
||||
*/
|
||||
struct policy_t {
|
||||
|
||||
/**
|
||||
* @brief Get own id to use for identification.
|
||||
*
|
||||
* Returned object is not getting cloned.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return own id
|
||||
*/
|
||||
identification_t *(*get_my_id) (policy_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get id of communication partner.
|
||||
*
|
||||
* Returned object is not getting cloned.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return other id
|
||||
*/
|
||||
identification_t *(*get_other_id) (policy_t *this);
|
||||
|
||||
/**
|
||||
* @brief Update own ID.
|
||||
*
|
||||
* It may be necessary to uptdate own ID, as it
|
||||
* is set to %any or to e.g. *@strongswan.org in
|
||||
* some cases.
|
||||
* Old ID is destroyed, new one NOT cloned.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param my_id new ID to set as my_id
|
||||
*/
|
||||
void (*update_my_id) (policy_t *this, identification_t *my_id);
|
||||
|
||||
/**
|
||||
* @brief Update others ID.
|
||||
*
|
||||
* It may be necessary to uptdate others ID, as it
|
||||
* is set to %any or to e.g. *@strongswan.org in
|
||||
* some cases.
|
||||
* Old ID is destroyed, new one NOT cloned.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param other_id new ID to set as other_id
|
||||
*/
|
||||
void (*update_other_id) (policy_t *this, identification_t *other_id);
|
||||
|
||||
/**
|
||||
* @brief Update own address in traffic selectors.
|
||||
*
|
||||
* Update own 0.0.0.0 address in traffic selectors
|
||||
* with supplied one. The size of the subnet will be
|
||||
* set to /32.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param my_host new address to set in traffic selectors
|
||||
*/
|
||||
void (*update_my_ts) (policy_t *this, host_t *my_host);
|
||||
|
||||
/**
|
||||
* @brief Update others address in traffic selectors.
|
||||
*
|
||||
* Update remote 0.0.0.0 address in traffic selectors
|
||||
* with supplied one. The size of the subnet will be
|
||||
* set to /32.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param other_host new address to set in traffic selectors
|
||||
*/
|
||||
void (*update_other_ts) (policy_t *this, host_t *other_host);
|
||||
|
||||
/**
|
||||
* @brief Get configured traffic selectors for our site.
|
||||
*
|
||||
* Returns a list with all traffic selectors for the local
|
||||
* site. List and items MUST NOT be freed nor modified.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return list with traffic selectors
|
||||
*/
|
||||
linked_list_t *(*get_my_traffic_selectors) (policy_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get configured traffic selectors for others site.
|
||||
*
|
||||
* Returns a list with all traffic selectors for the remote
|
||||
* site. List and items MUST NOT be freed nor modified.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return list with traffic selectors
|
||||
*/
|
||||
linked_list_t *(*get_other_traffic_selectors) (policy_t *this);
|
||||
|
||||
/**
|
||||
* @brief Select traffic selectors from a supplied list for local site.
|
||||
*
|
||||
* Resulted list and traffic selectors must be destroyed after usage.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param supplied linked list with traffic selectors
|
||||
* @return list containing the selected traffic selectors
|
||||
*/
|
||||
linked_list_t *(*select_my_traffic_selectors) (policy_t *this, linked_list_t *supplied);
|
||||
|
||||
/**
|
||||
* @brief Select traffic selectors from a supplied list for remote site.
|
||||
*
|
||||
* Resulted list and traffic selectors must be destroyed after usage.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param supplied linked list with traffic selectors
|
||||
* @return list containing the selected traffic selectors
|
||||
*/
|
||||
linked_list_t *(*select_other_traffic_selectors) (policy_t *this, linked_list_t *supplied);
|
||||
|
||||
/**
|
||||
* @brief Get the list of internally stored proposals.
|
||||
*
|
||||
* Rembember: policy_t does store proposals for AH/ESP,
|
||||
* IKE proposals are in the connection_t
|
||||
*
|
||||
* @warning List and Items are still owned by policy and MUST NOT
|
||||
* be manipulated or freed!
|
||||
*
|
||||
* @param this calling object
|
||||
* @return lists with proposals
|
||||
*/
|
||||
linked_list_t *(*get_proposals) (policy_t *this);
|
||||
|
||||
/**
|
||||
* @brief Select a proposal from a supplied list.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param proposals list from from wich proposals are selected
|
||||
* @return selected proposal, or NULL if nothing matches
|
||||
*/
|
||||
proposal_t *(*select_proposal) (policy_t *this, linked_list_t *proposals);
|
||||
|
||||
/**
|
||||
* @brief Add a traffic selector to the list for local site.
|
||||
*
|
||||
* After add, proposal is owned by policy.
|
||||
*
|
||||
* @warning Do not add while other threads are reading.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param traffic_selector traffic_selector to add
|
||||
*/
|
||||
void (*add_my_traffic_selector) (policy_t *this, traffic_selector_t *traffic_selector);
|
||||
|
||||
/**
|
||||
* @brief Add a traffic selector to the list for remote site.
|
||||
*
|
||||
* After add, proposal is owned by policy.
|
||||
*
|
||||
* @warning Do not add while other threads are reading.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param traffic_selector traffic_selector to add
|
||||
*/
|
||||
void (*add_other_traffic_selector) (policy_t *this, traffic_selector_t *traffic_selector);
|
||||
|
||||
/**
|
||||
* @brief Add a proposal to the list.
|
||||
*
|
||||
* The proposals are stored by priority, first added
|
||||
* is the most prefered.
|
||||
*
|
||||
* @warning Do not add while other threads are reading.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param proposal proposal to add
|
||||
*/
|
||||
void (*add_proposal) (policy_t *this, proposal_t *proposal);
|
||||
|
||||
/**
|
||||
* @brief Clone a policy.
|
||||
*
|
||||
* @param this policy to clone
|
||||
* @return clone of it
|
||||
*/
|
||||
policy_t *(*clone) (policy_t *this);
|
||||
|
||||
/**
|
||||
* @brief Destroys the policy object
|
||||
*
|
||||
* @param this calling object
|
||||
*/
|
||||
void (*destroy) (policy_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Create a configuration object for IKE_AUTH and later.
|
||||
*
|
||||
* @param my_id identification_t for ourselves
|
||||
* @param other_id identification_t for the remote guy
|
||||
* @return policy_t object
|
||||
*
|
||||
* @ingroup config
|
||||
*/
|
||||
policy_t *policy_create(identification_t *my_id, identification_t *other_id);
|
||||
|
||||
#endif /* POLICY_H_ */
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* @file policy_store.h
|
||||
*
|
||||
* @brief Interface policy_store_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef POLICY_STORE_H_
|
||||
#define POLICY_STORE_H_
|
||||
|
||||
#include <types.h>
|
||||
#include <config/policies/policy.h>
|
||||
|
||||
|
||||
typedef struct policy_store_t policy_store_t;
|
||||
|
||||
/**
|
||||
* @brief The interface for a store of policy_t's.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - stroke_create()
|
||||
*
|
||||
* @ingroup config
|
||||
*/
|
||||
struct policy_store_t {
|
||||
|
||||
/**
|
||||
* @brief Returns a policy identified by two IDs.
|
||||
*
|
||||
* The returned policy gets created/cloned and therefore must be
|
||||
* destroyed by the caller.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param my_id own ID of the policy
|
||||
* @param other_id others ID of the policy
|
||||
* @return
|
||||
* - matching policy_t, if found
|
||||
* - NULL otherwise
|
||||
*/
|
||||
policy_t *(*get_policy) (policy_store_t *this, identification_t *my_id, identification_t *other_id);
|
||||
|
||||
/**
|
||||
* @brief Add a policy to the list.
|
||||
*
|
||||
* The policy is owned by the store after the call. Do
|
||||
* not modify nor free.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param policy policy to add
|
||||
*/
|
||||
void (*add_policy) (policy_store_t *this, policy_t *policy);
|
||||
|
||||
/**
|
||||
* @brief Destroys a policy_store_t object.
|
||||
*
|
||||
* @param this calling object
|
||||
*/
|
||||
void (*destroy) (policy_store_t *this);
|
||||
};
|
||||
|
||||
#endif /*POLICY_STORE_H_*/
|
||||
@@ -0,0 +1,642 @@
|
||||
/**
|
||||
* @file proposal.c
|
||||
*
|
||||
* @brief Implementation of proposal_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "proposal.h"
|
||||
|
||||
#include <utils/linked_list.h>
|
||||
#include <utils/identification.h>
|
||||
#include <utils/logger.h>
|
||||
|
||||
|
||||
/**
|
||||
* String mappings for protocol_id_t.
|
||||
*/
|
||||
mapping_t protocol_id_m[] = {
|
||||
{PROTO_NONE, "PROTO_NONE"},
|
||||
{PROTO_IKE, "PROTO_IKE"},
|
||||
{PROTO_AH, "PROTO_AH"},
|
||||
{PROTO_ESP, "PROTO_ESP"},
|
||||
{MAPPING_END, NULL}
|
||||
};
|
||||
|
||||
/**
|
||||
* String mappings for transform_type_t.
|
||||
*/
|
||||
mapping_t transform_type_m[] = {
|
||||
{UNDEFINED_TRANSFORM_TYPE, "UNDEFINED_TRANSFORM_TYPE"},
|
||||
{ENCRYPTION_ALGORITHM, "ENCRYPTION_ALGORITHM"},
|
||||
{PSEUDO_RANDOM_FUNCTION, "PSEUDO_RANDOM_FUNCTION"},
|
||||
{INTEGRITY_ALGORITHM, "INTEGRITY_ALGORITHM"},
|
||||
{DIFFIE_HELLMAN_GROUP, "DIFFIE_HELLMAN_GROUP"},
|
||||
{EXTENDED_SEQUENCE_NUMBERS, "EXTENDED_SEQUENCE_NUMBERS"},
|
||||
{MAPPING_END, NULL}
|
||||
};
|
||||
|
||||
/**
|
||||
* String mappings for extended_sequence_numbers_t.
|
||||
*/
|
||||
mapping_t extended_sequence_numbers_m[] = {
|
||||
{NO_EXT_SEQ_NUMBERS, "NO_EXT_SEQ_NUMBERS"},
|
||||
{EXT_SEQ_NUMBERS, "EXT_SEQ_NUMBERS"},
|
||||
{MAPPING_END, NULL}
|
||||
};
|
||||
|
||||
|
||||
typedef struct protocol_proposal_t protocol_proposal_t;
|
||||
|
||||
/**
|
||||
* substructure which holds all data algos for a specific protocol
|
||||
*/
|
||||
struct protocol_proposal_t {
|
||||
/**
|
||||
* protocol (ESP or AH)
|
||||
*/
|
||||
protocol_id_t protocol;
|
||||
|
||||
/**
|
||||
* priority ordered list of encryption algorithms
|
||||
*/
|
||||
linked_list_t *encryption_algos;
|
||||
|
||||
/**
|
||||
* priority ordered list of integrity algorithms
|
||||
*/
|
||||
linked_list_t *integrity_algos;
|
||||
|
||||
/**
|
||||
* priority ordered list of pseudo random functions
|
||||
*/
|
||||
linked_list_t *prf_algos;
|
||||
|
||||
/**
|
||||
* priority ordered list of dh groups
|
||||
*/
|
||||
linked_list_t *dh_groups;
|
||||
|
||||
/**
|
||||
* priority ordered list of extended sequence number flags
|
||||
*/
|
||||
linked_list_t *esns;
|
||||
|
||||
/**
|
||||
* senders SPI
|
||||
*/
|
||||
chunk_t spi;
|
||||
};
|
||||
|
||||
|
||||
typedef struct private_proposal_t private_proposal_t;
|
||||
|
||||
/**
|
||||
* Private data of an proposal_t object
|
||||
*/
|
||||
struct private_proposal_t {
|
||||
|
||||
/**
|
||||
* Public part
|
||||
*/
|
||||
proposal_t public;
|
||||
|
||||
/**
|
||||
* number of this proposal, as used in the payload
|
||||
*/
|
||||
u_int8_t number;
|
||||
|
||||
/**
|
||||
* list of protocol_proposal_t's
|
||||
*/
|
||||
linked_list_t *protocol_proposals;
|
||||
};
|
||||
|
||||
/**
|
||||
* Look up a protocol_proposal, or create one if necessary...
|
||||
*/
|
||||
static protocol_proposal_t *get_protocol_proposal(private_proposal_t *this, protocol_id_t proto, bool create)
|
||||
{
|
||||
protocol_proposal_t *proto_proposal = NULL, *current_proto_proposal;;
|
||||
iterator_t *iterator;
|
||||
|
||||
/* find our protocol in the proposals */
|
||||
iterator = this->protocol_proposals->create_iterator(this->protocol_proposals, TRUE);
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
iterator->current(iterator, (void**)¤t_proto_proposal);
|
||||
if (current_proto_proposal->protocol == proto)
|
||||
{
|
||||
proto_proposal = current_proto_proposal;
|
||||
break;
|
||||
}
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
if (!proto_proposal && create)
|
||||
{
|
||||
/* nope, create a new one */
|
||||
proto_proposal = malloc_thing(protocol_proposal_t);
|
||||
proto_proposal->protocol = proto;
|
||||
proto_proposal->encryption_algos = linked_list_create();
|
||||
proto_proposal->integrity_algos = linked_list_create();
|
||||
proto_proposal->prf_algos = linked_list_create();
|
||||
proto_proposal->dh_groups = linked_list_create();
|
||||
proto_proposal->esns = linked_list_create();
|
||||
if (proto == PROTO_IKE)
|
||||
{
|
||||
proto_proposal->spi.len = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
proto_proposal->spi.len = 4;
|
||||
}
|
||||
proto_proposal->spi.ptr = malloc(proto_proposal->spi.len);
|
||||
/* add to the list */
|
||||
this->protocol_proposals->insert_last(this->protocol_proposals, (void*)proto_proposal);
|
||||
}
|
||||
return proto_proposal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add algorithm/keysize to a algorithm list
|
||||
*/
|
||||
static void add_algo(linked_list_t *list, u_int8_t algo, size_t key_size)
|
||||
{
|
||||
algorithm_t *algo_key = malloc_thing(algorithm_t);
|
||||
|
||||
algo_key->algorithm = algo;
|
||||
algo_key->key_size = key_size;
|
||||
list->insert_last(list, (void*)algo_key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements proposal_t.add_algorithm
|
||||
*/
|
||||
static void add_algorithm(private_proposal_t *this, protocol_id_t proto, transform_type_t type, u_int16_t algo, size_t key_size)
|
||||
{
|
||||
protocol_proposal_t *proto_proposal = get_protocol_proposal(this, proto, TRUE);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case ENCRYPTION_ALGORITHM:
|
||||
add_algo(proto_proposal->encryption_algos, algo, key_size);
|
||||
break;
|
||||
case INTEGRITY_ALGORITHM:
|
||||
add_algo(proto_proposal->integrity_algos, algo, key_size);
|
||||
break;
|
||||
case PSEUDO_RANDOM_FUNCTION:
|
||||
add_algo(proto_proposal->prf_algos, algo, key_size);
|
||||
break;
|
||||
case DIFFIE_HELLMAN_GROUP:
|
||||
add_algo(proto_proposal->dh_groups, algo, 0);
|
||||
break;
|
||||
case EXTENDED_SEQUENCE_NUMBERS:
|
||||
add_algo(proto_proposal->esns, algo, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements proposal_t.get_algorithm.
|
||||
*/
|
||||
static bool get_algorithm(private_proposal_t *this, protocol_id_t proto, transform_type_t type, algorithm_t** algo)
|
||||
{
|
||||
linked_list_t * list;
|
||||
protocol_proposal_t *proto_proposal = get_protocol_proposal(this, proto, FALSE);
|
||||
|
||||
if (proto_proposal == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
switch (type)
|
||||
{
|
||||
case ENCRYPTION_ALGORITHM:
|
||||
list = proto_proposal->encryption_algos;
|
||||
break;
|
||||
case INTEGRITY_ALGORITHM:
|
||||
list = proto_proposal->integrity_algos;
|
||||
break;
|
||||
case PSEUDO_RANDOM_FUNCTION:
|
||||
list = proto_proposal->prf_algos;
|
||||
break;
|
||||
case DIFFIE_HELLMAN_GROUP:
|
||||
list = proto_proposal->dh_groups;
|
||||
break;
|
||||
case EXTENDED_SEQUENCE_NUMBERS:
|
||||
list = proto_proposal->esns;
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
if (list->get_first(list, (void**)algo) != SUCCESS)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements proposal_t.create_algorithm_iterator.
|
||||
*/
|
||||
static iterator_t *create_algorithm_iterator(private_proposal_t *this, protocol_id_t proto, transform_type_t type)
|
||||
{
|
||||
protocol_proposal_t *proto_proposal = get_protocol_proposal(this, proto, FALSE);
|
||||
if (proto_proposal == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case ENCRYPTION_ALGORITHM:
|
||||
return proto_proposal->encryption_algos->create_iterator(proto_proposal->encryption_algos, TRUE);
|
||||
case INTEGRITY_ALGORITHM:
|
||||
return proto_proposal->integrity_algos->create_iterator(proto_proposal->integrity_algos, TRUE);
|
||||
case PSEUDO_RANDOM_FUNCTION:
|
||||
return proto_proposal->prf_algos->create_iterator(proto_proposal->prf_algos, TRUE);
|
||||
case DIFFIE_HELLMAN_GROUP:
|
||||
return proto_proposal->dh_groups->create_iterator(proto_proposal->dh_groups, TRUE);
|
||||
case EXTENDED_SEQUENCE_NUMBERS:
|
||||
return proto_proposal->esns->create_iterator(proto_proposal->esns, TRUE);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a matching alg/keysize in two linked lists
|
||||
*/
|
||||
static bool select_algo(linked_list_t *first, linked_list_t *second, bool *add, u_int16_t *alg, size_t *key_size)
|
||||
{
|
||||
iterator_t *first_iter, *second_iter;
|
||||
algorithm_t *first_alg, *second_alg;
|
||||
|
||||
/* if in both are zero algorithms specified, we HAVE a match */
|
||||
if (first->get_count(first) == 0 && second->get_count(second) == 0)
|
||||
{
|
||||
*add = FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
first_iter = first->create_iterator(first, TRUE);
|
||||
second_iter = second->create_iterator(second, TRUE);
|
||||
/* compare algs, order of algs in "first" is preferred */
|
||||
while (first_iter->has_next(first_iter))
|
||||
{
|
||||
first_iter->current(first_iter, (void**)&first_alg);
|
||||
second_iter->reset(second_iter);
|
||||
while (second_iter->has_next(second_iter))
|
||||
{
|
||||
second_iter->current(second_iter, (void**)&second_alg);
|
||||
if (first_alg->algorithm == second_alg->algorithm &&
|
||||
first_alg->key_size == second_alg->key_size)
|
||||
{
|
||||
/* ok, we have an algorithm */
|
||||
*alg = first_alg->algorithm;
|
||||
*key_size = first_alg->key_size;
|
||||
*add = TRUE;
|
||||
first_iter->destroy(first_iter);
|
||||
second_iter->destroy(second_iter);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* no match in all comparisons */
|
||||
first_iter->destroy(first_iter);
|
||||
second_iter->destroy(second_iter);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements proposal_t.select.
|
||||
*/
|
||||
static proposal_t *select_proposal(private_proposal_t *this, private_proposal_t *other)
|
||||
{
|
||||
proposal_t *selected;
|
||||
u_int16_t algo;
|
||||
size_t key_size;
|
||||
iterator_t *iterator;
|
||||
protocol_proposal_t *this_prop, *other_prop;
|
||||
protocol_id_t proto;
|
||||
bool add;
|
||||
u_int64_t spi;
|
||||
|
||||
/* empty proposal? no match */
|
||||
if (this->protocol_proposals->get_count(this->protocol_proposals) == 0 ||
|
||||
other->protocol_proposals->get_count(other->protocol_proposals) == 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
/* they MUST have the same amount of protocols */
|
||||
if (this->protocol_proposals->get_count(this->protocol_proposals) !=
|
||||
other->protocol_proposals->get_count(other->protocol_proposals))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
selected = proposal_create(this->number);
|
||||
|
||||
/* iterate over supplied proposals */
|
||||
iterator = other->protocol_proposals->create_iterator(other->protocol_proposals, TRUE);
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
iterator->current(iterator, (void**)&other_prop);
|
||||
/* get the proposal with the same protocol */
|
||||
proto = other_prop->protocol;
|
||||
this_prop = get_protocol_proposal(this, proto, FALSE);
|
||||
|
||||
if (this_prop == NULL)
|
||||
{
|
||||
iterator->destroy(iterator);
|
||||
selected->destroy(selected);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* select encryption algorithm */
|
||||
if (select_algo(this_prop->encryption_algos, other_prop->encryption_algos, &add, &algo, &key_size))
|
||||
{
|
||||
if (add)
|
||||
{
|
||||
selected->add_algorithm(selected, proto, ENCRYPTION_ALGORITHM, algo, key_size);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
iterator->destroy(iterator);
|
||||
selected->destroy(selected);
|
||||
return NULL;
|
||||
}
|
||||
/* select integrity algorithm */
|
||||
if (select_algo(this_prop->integrity_algos, other_prop->integrity_algos, &add, &algo, &key_size))
|
||||
{
|
||||
if (add)
|
||||
{
|
||||
selected->add_algorithm(selected, proto, INTEGRITY_ALGORITHM, algo, key_size);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
iterator->destroy(iterator);
|
||||
selected->destroy(selected);
|
||||
return NULL;
|
||||
}
|
||||
/* select prf algorithm */
|
||||
if (select_algo(this_prop->prf_algos, other_prop->prf_algos, &add, &algo, &key_size))
|
||||
{
|
||||
if (add)
|
||||
{
|
||||
selected->add_algorithm(selected, proto, PSEUDO_RANDOM_FUNCTION, algo, key_size);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
iterator->destroy(iterator);
|
||||
selected->destroy(selected);
|
||||
return NULL;
|
||||
}
|
||||
/* select a DH-group */
|
||||
if (select_algo(this_prop->dh_groups, other_prop->dh_groups, &add, &algo, &key_size))
|
||||
{
|
||||
if (add)
|
||||
{
|
||||
selected->add_algorithm(selected, proto, DIFFIE_HELLMAN_GROUP, algo, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
iterator->destroy(iterator);
|
||||
selected->destroy(selected);
|
||||
return NULL;
|
||||
}
|
||||
/* select if we use ESNs */
|
||||
if (select_algo(this_prop->esns, other_prop->esns, &add, &algo, &key_size))
|
||||
{
|
||||
if (add)
|
||||
{
|
||||
selected->add_algorithm(selected, proto, EXTENDED_SEQUENCE_NUMBERS, algo, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
iterator->destroy(iterator);
|
||||
selected->destroy(selected);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
/* apply spis from "other" */
|
||||
spi = other->public.get_spi(&(other->public), PROTO_AH);
|
||||
if (spi)
|
||||
{
|
||||
selected->set_spi(selected, PROTO_AH, spi);
|
||||
}
|
||||
spi = other->public.get_spi(&(other->public), PROTO_ESP);
|
||||
if (spi)
|
||||
{
|
||||
selected->set_spi(selected, PROTO_ESP, spi);
|
||||
}
|
||||
|
||||
/* everything matched, return new proposal */
|
||||
return selected;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements proposal_t.get_number.
|
||||
*/
|
||||
static u_int8_t get_number(private_proposal_t *this)
|
||||
{
|
||||
return this->number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements proposal_t.get_protocols.
|
||||
*/
|
||||
static void get_protocols(private_proposal_t *this, protocol_id_t ids[2])
|
||||
{
|
||||
iterator_t *iterator = this->protocol_proposals->create_iterator(this->protocol_proposals, TRUE);
|
||||
u_int i = 0;
|
||||
|
||||
ids[0] = PROTO_NONE;
|
||||
ids[1] = PROTO_NONE;
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
protocol_proposal_t *proto_prop;
|
||||
iterator->current(iterator, (void**)&proto_prop);
|
||||
ids[i++] = proto_prop->protocol;
|
||||
if (i>1)
|
||||
{
|
||||
/* should not happen, but who knows */
|
||||
break;
|
||||
}
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements proposal_t.set_spi.
|
||||
*/
|
||||
static void set_spi(private_proposal_t *this, protocol_id_t proto, u_int64_t spi)
|
||||
{
|
||||
protocol_proposal_t *proto_proposal = get_protocol_proposal(this, proto, FALSE);
|
||||
if (proto_proposal)
|
||||
{
|
||||
if (proto == PROTO_AH || proto == PROTO_ESP)
|
||||
{
|
||||
*((u_int32_t*)proto_proposal->spi.ptr) = (u_int32_t)spi;
|
||||
}
|
||||
else
|
||||
{
|
||||
*((u_int64_t*)proto_proposal->spi.ptr) = spi;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements proposal_t.get_spi.
|
||||
*/
|
||||
static u_int64_t get_spi(private_proposal_t *this, protocol_id_t proto)
|
||||
{
|
||||
protocol_proposal_t *proto_proposal = get_protocol_proposal(this, proto, FALSE);
|
||||
if (proto_proposal)
|
||||
{
|
||||
if (proto == PROTO_AH || proto == PROTO_ESP)
|
||||
{
|
||||
return (u_int64_t)*((u_int32_t*)proto_proposal->spi.ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
return *((u_int64_t*)proto_proposal->spi.ptr);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone a algorithm list
|
||||
*/
|
||||
static void clone_algo_list(linked_list_t *list, linked_list_t *clone_list)
|
||||
{
|
||||
algorithm_t *algo, *clone_algo;
|
||||
iterator_t *iterator = list->create_iterator(list, TRUE);
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
iterator->current(iterator, (void**)&algo);
|
||||
clone_algo = malloc_thing(algorithm_t);
|
||||
memcpy(clone_algo, algo, sizeof(algorithm_t));
|
||||
clone_list->insert_last(clone_list, (void*)clone_algo);
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements proposal_t.clone
|
||||
*/
|
||||
static proposal_t *clone(private_proposal_t *this)
|
||||
{
|
||||
private_proposal_t *clone = (private_proposal_t*)proposal_create(this->number);
|
||||
|
||||
iterator_t *iterator = this->protocol_proposals->create_iterator(this->protocol_proposals, TRUE);
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
protocol_proposal_t *proto_prop, *clone_proto_prop;
|
||||
iterator->current(iterator, (void**)&proto_prop);
|
||||
|
||||
clone_proto_prop = get_protocol_proposal(clone, proto_prop->protocol, TRUE);
|
||||
memcpy(clone_proto_prop->spi.ptr, proto_prop->spi.ptr, clone_proto_prop->spi.len);
|
||||
|
||||
clone_algo_list(proto_prop->encryption_algos, clone_proto_prop->encryption_algos);
|
||||
clone_algo_list(proto_prop->integrity_algos, clone_proto_prop->integrity_algos);
|
||||
clone_algo_list(proto_prop->prf_algos, clone_proto_prop->prf_algos);
|
||||
clone_algo_list(proto_prop->dh_groups, clone_proto_prop->dh_groups);
|
||||
clone_algo_list(proto_prop->esns, clone_proto_prop->esns);
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
return &clone->public;
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees all list items and destroys the list
|
||||
*/
|
||||
static void free_algo_list(linked_list_t *list)
|
||||
{
|
||||
algorithm_t *algo;
|
||||
|
||||
while(list->get_count(list) > 0)
|
||||
{
|
||||
list->remove_last(list, (void**)&algo);
|
||||
free(algo);
|
||||
}
|
||||
list->destroy(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements proposal_t.destroy.
|
||||
*/
|
||||
static void destroy(private_proposal_t *this)
|
||||
{
|
||||
while(this->protocol_proposals->get_count(this->protocol_proposals) > 0)
|
||||
{
|
||||
protocol_proposal_t *proto_prop;
|
||||
this->protocol_proposals->remove_last(this->protocol_proposals, (void**)&proto_prop);
|
||||
|
||||
free_algo_list(proto_prop->encryption_algos);
|
||||
free_algo_list(proto_prop->integrity_algos);
|
||||
free_algo_list(proto_prop->prf_algos);
|
||||
free_algo_list(proto_prop->dh_groups);
|
||||
free_algo_list(proto_prop->esns);
|
||||
|
||||
free(proto_prop->spi.ptr);
|
||||
free(proto_prop);
|
||||
}
|
||||
this->protocol_proposals->destroy(this->protocol_proposals);
|
||||
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Describtion in header-file
|
||||
*/
|
||||
proposal_t *proposal_create(u_int8_t number)
|
||||
{
|
||||
private_proposal_t *this = malloc_thing(private_proposal_t);
|
||||
|
||||
this->public.add_algorithm = (void (*)(proposal_t*,protocol_id_t,transform_type_t,u_int16_t,size_t))add_algorithm;
|
||||
this->public.create_algorithm_iterator = (iterator_t* (*)(proposal_t*,protocol_id_t,transform_type_t))create_algorithm_iterator;
|
||||
this->public.get_algorithm = (bool (*)(proposal_t*,protocol_id_t,transform_type_t,algorithm_t**))get_algorithm;
|
||||
this->public.select = (proposal_t* (*)(proposal_t*,proposal_t*))select_proposal;
|
||||
this->public.get_number = (u_int8_t (*)(proposal_t*))get_number;
|
||||
this->public.get_protocols = (void(*)(proposal_t *this, protocol_id_t ids[2]))get_protocols;
|
||||
this->public.set_spi = (void(*)(proposal_t*,protocol_id_t,u_int64_t spi))set_spi;
|
||||
this->public.get_spi = (u_int64_t(*)(proposal_t*,protocol_id_t))get_spi;
|
||||
this->public.clone = (proposal_t*(*)(proposal_t*))clone;
|
||||
this->public.destroy = (void(*)(proposal_t*))destroy;
|
||||
|
||||
/* init private members*/
|
||||
this->number = number;
|
||||
this->protocol_proposals = linked_list_create();
|
||||
|
||||
return (&this->public);
|
||||
}
|
||||
@@ -0,0 +1,269 @@
|
||||
/**
|
||||
* @file proposal.h
|
||||
*
|
||||
* @brief Interface of proposal_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef PROPOSAL_H_
|
||||
#define PROPOSAL_H_
|
||||
|
||||
#include <types.h>
|
||||
#include <utils/identification.h>
|
||||
#include <utils/linked_list.h>
|
||||
#include <utils/host.h>
|
||||
#include <crypto/crypters/crypter.h>
|
||||
#include <crypto/signers/signer.h>
|
||||
#include <crypto/diffie_hellman.h>
|
||||
#include <config/traffic_selector.h>
|
||||
|
||||
|
||||
typedef enum protocol_id_t protocol_id_t;
|
||||
|
||||
/**
|
||||
* Protocol ID of a proposal.
|
||||
*
|
||||
* @ingroup config
|
||||
*/
|
||||
enum protocol_id_t {
|
||||
PROTO_NONE = 0,
|
||||
PROTO_IKE = 1,
|
||||
PROTO_AH = 2,
|
||||
PROTO_ESP = 3,
|
||||
};
|
||||
|
||||
/**
|
||||
* String mappings for protocol_id_t.
|
||||
*
|
||||
* @ingroup config
|
||||
*/
|
||||
extern mapping_t protocol_id_m[];
|
||||
|
||||
|
||||
typedef enum transform_type_t transform_type_t;
|
||||
|
||||
/**
|
||||
* Type of a transform, as in IKEv2 RFC 3.3.2.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
enum transform_type_t {
|
||||
UNDEFINED_TRANSFORM_TYPE = 241,
|
||||
ENCRYPTION_ALGORITHM = 1,
|
||||
PSEUDO_RANDOM_FUNCTION = 2,
|
||||
INTEGRITY_ALGORITHM = 3,
|
||||
DIFFIE_HELLMAN_GROUP = 4,
|
||||
EXTENDED_SEQUENCE_NUMBERS = 5
|
||||
};
|
||||
|
||||
/**
|
||||
* String mappings for transform_type_t.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
extern mapping_t transform_type_m[];
|
||||
|
||||
|
||||
typedef enum extended_sequence_numbers_t extended_sequence_numbers_t;
|
||||
|
||||
/**
|
||||
* Extended sequence numbers, as in IKEv2 RFC 3.3.2.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
enum extended_sequence_numbers_t {
|
||||
NO_EXT_SEQ_NUMBERS = 0,
|
||||
EXT_SEQ_NUMBERS = 1
|
||||
};
|
||||
|
||||
/**
|
||||
* String mappings for extended_sequence_numbers_t.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
extern mapping_t extended_sequence_numbers_m[];
|
||||
|
||||
|
||||
typedef struct algorithm_t algorithm_t;
|
||||
|
||||
/**
|
||||
* Struct used to store different kinds of algorithms. The internal
|
||||
* lists of algorithms contain such structures.
|
||||
*/
|
||||
struct algorithm_t {
|
||||
/**
|
||||
* Value from an encryption_algorithm_t/integrity_algorithm_t/...
|
||||
*/
|
||||
u_int16_t algorithm;
|
||||
|
||||
/**
|
||||
* the associated key size, or zero if not needed
|
||||
*/
|
||||
u_int16_t key_size;
|
||||
};
|
||||
|
||||
typedef struct proposal_t proposal_t;
|
||||
|
||||
/**
|
||||
* @brief Stores a set of algorithms used for an SA.
|
||||
*
|
||||
* A proposal stores algorithms for a specific
|
||||
* protocol. It can store algorithms for more than
|
||||
* one protocol (e.g. AH and ESP). Then the proposal
|
||||
* means both protocols must be used.
|
||||
* A proposal may contain more than one algorithm
|
||||
* of the same kind. ONE of them can be selected.
|
||||
*
|
||||
* @warning This class is NOT thread-save!
|
||||
*
|
||||
* @b Constructors:
|
||||
* - proposal_create()
|
||||
*
|
||||
* @ingroup config
|
||||
*/
|
||||
struct proposal_t {
|
||||
|
||||
/**
|
||||
* @brief Add an algorithm to the proposal.
|
||||
*
|
||||
* The algorithms are stored by priority, first added
|
||||
* is the most preferred.
|
||||
* Key size is only needed for encryption algorithms
|
||||
* with variable key size (such as AES). Must be set
|
||||
* to zero if key size is not specified.
|
||||
* The alg parameter accepts encryption_algorithm_t,
|
||||
* integrity_algorithm_t, dh_group_number_t and
|
||||
* extended_sequence_numbers_t.
|
||||
*
|
||||
* @warning Do not add while other threads are reading.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param proto desired protocol
|
||||
* @param type kind of algorithm
|
||||
* @param alg identifier for algorithm
|
||||
* @param key_size key size to use
|
||||
*/
|
||||
void (*add_algorithm) (proposal_t *this, protocol_id_t proto, transform_type_t type, u_int16_t alg, size_t key_size);
|
||||
|
||||
/**
|
||||
* @brief Get an iterator over algorithms for a specifc protocol/algo type.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param proto desired protocol
|
||||
* @param type kind of algorithm
|
||||
* @return iterator over algorithms
|
||||
*/
|
||||
iterator_t *(*create_algorithm_iterator) (proposal_t *this, protocol_id_t proto, transform_type_t type);
|
||||
|
||||
/**
|
||||
* @brief Get the algorithm for a type to use.
|
||||
*
|
||||
* If there are multiple algorithms, only the first is returned.
|
||||
* Result is still owned by proposal, do not modify!
|
||||
*
|
||||
* @param this calling object
|
||||
* @param proto desired protocol
|
||||
* @param type kind of algorithm
|
||||
* @param[out] algo pointer which receives algorithm and key size
|
||||
* @return TRUE if algorithm of this kind available
|
||||
*/
|
||||
bool (*get_algorithm) (proposal_t *this, protocol_id_t proto, transform_type_t type, algorithm_t** algo);
|
||||
|
||||
/**
|
||||
* @brief Compare two proposal, and select a matching subset.
|
||||
*
|
||||
* If the proposals are for the same protocols (AH/ESP), they are
|
||||
* compared. If they have at least one algorithm of each type
|
||||
* in common, a resulting proposal of this kind is created.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param other proposal to compair agains
|
||||
* @return
|
||||
* - selected proposal, if possible
|
||||
* - NULL, if proposals don't match
|
||||
*/
|
||||
proposal_t *(*select) (proposal_t *this, proposal_t *other);
|
||||
|
||||
/**
|
||||
* @brief Get the number set on construction.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return number
|
||||
*/
|
||||
u_int8_t (*get_number) (proposal_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get the protocol ids in the proposals.
|
||||
*
|
||||
* With AH and ESP, there could be two protocols in one
|
||||
* proposal.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param ids array of protocol ids,
|
||||
*/
|
||||
void (*get_protocols) (proposal_t *this, protocol_id_t ids[2]);
|
||||
|
||||
/**
|
||||
* @brief Get the spi for a specific protocol.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param proto AH/ESP
|
||||
* @return spi for proto
|
||||
*/
|
||||
u_int64_t (*get_spi) (proposal_t *this, protocol_id_t proto);
|
||||
|
||||
/**
|
||||
* @brief Set the spi for a specific protocol.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param proto AH/ESP
|
||||
* @param spi spi to set for proto
|
||||
*/
|
||||
void (*set_spi) (proposal_t *this, protocol_id_t proto, u_int64_t spi);
|
||||
|
||||
/**
|
||||
* @brief Clone a proposal.
|
||||
*
|
||||
* @param this proposal to clone
|
||||
* @return clone of it
|
||||
*/
|
||||
proposal_t *(*clone) (proposal_t *this);
|
||||
|
||||
/**
|
||||
* @brief Destroys the proposal object.
|
||||
*
|
||||
* @param this calling object
|
||||
*/
|
||||
void (*destroy) (proposal_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Create a child proposal for AH and/or ESP.
|
||||
*
|
||||
* Since the order of multiple proposals is important for
|
||||
* key derivation, we must assign them numbers as they
|
||||
* appear in the raw payload. Numbering starts at 1.
|
||||
*
|
||||
* @param number number of the proposal, as in the payload
|
||||
* @return proposal_t object
|
||||
*
|
||||
* @ingroup config
|
||||
*/
|
||||
proposal_t *proposal_create(u_int8_t number);
|
||||
|
||||
#endif /* PROPOSAL_H_ */
|
||||
@@ -0,0 +1,425 @@
|
||||
/**
|
||||
* @file traffic_selector.c
|
||||
*
|
||||
* @brief Implementation of traffic_selector_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "traffic_selector.h"
|
||||
|
||||
#include <utils/linked_list.h>
|
||||
#include <utils/identification.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct private_traffic_selector_t private_traffic_selector_t;
|
||||
|
||||
/**
|
||||
* Private data of an traffic_selector_t object
|
||||
*/
|
||||
struct private_traffic_selector_t {
|
||||
|
||||
/**
|
||||
* Public part
|
||||
*/
|
||||
traffic_selector_t public;
|
||||
|
||||
/**
|
||||
* Type of address
|
||||
*/
|
||||
ts_type_t type;
|
||||
|
||||
/**
|
||||
* IP protocol (UDP, TCP, ICMP, ...)
|
||||
*/
|
||||
u_int8_t protocol;
|
||||
|
||||
/**
|
||||
* begin of address range, host order
|
||||
*/
|
||||
union {
|
||||
u_int32_t from_addr_ipv4;
|
||||
};
|
||||
|
||||
/**
|
||||
* end of address range, host order
|
||||
*/
|
||||
union {
|
||||
u_int32_t to_addr_ipv4;
|
||||
};
|
||||
|
||||
/**
|
||||
* begin of port range
|
||||
*/
|
||||
u_int16_t from_port;
|
||||
|
||||
/**
|
||||
* end of port range
|
||||
*/
|
||||
u_int16_t to_port;
|
||||
};
|
||||
|
||||
/**
|
||||
* internal generic constructor
|
||||
*/
|
||||
static private_traffic_selector_t *traffic_selector_create(u_int8_t protocol, ts_type_t type, u_int16_t from_port, u_int16_t to_port);
|
||||
|
||||
/**
|
||||
* implements traffic_selector_t.get_subset
|
||||
*/
|
||||
static traffic_selector_t *get_subset(private_traffic_selector_t *this, private_traffic_selector_t *other)
|
||||
{
|
||||
if ((this->type == TS_IPV4_ADDR_RANGE) &&
|
||||
(other->type == TS_IPV4_ADDR_RANGE) &&
|
||||
(this->protocol == other->protocol))
|
||||
{
|
||||
u_int32_t from_addr, to_addr;
|
||||
u_int16_t from_port, to_port;
|
||||
private_traffic_selector_t *new_ts;
|
||||
|
||||
/* calculate the maximum address range allowed for both */
|
||||
from_addr = max(this->from_addr_ipv4, other->from_addr_ipv4);
|
||||
to_addr = min(this->to_addr_ipv4, other->to_addr_ipv4);
|
||||
if (from_addr > to_addr)
|
||||
{
|
||||
/* no match */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* calculate the maximum port range allowed for both */
|
||||
from_port = max(this->from_port, other->from_port);
|
||||
to_port = min(this->to_port, other->to_port);
|
||||
if (from_port > to_port)
|
||||
{
|
||||
/* no match */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* got a match, return it */
|
||||
new_ts = traffic_selector_create(this->protocol, this->type, from_port, to_port);
|
||||
new_ts->from_addr_ipv4 = from_addr;
|
||||
new_ts->to_addr_ipv4 = to_addr;
|
||||
new_ts->type = TS_IPV4_ADDR_RANGE;
|
||||
return &(new_ts->public);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements traffic_selector_t.get_from_address.
|
||||
*/
|
||||
static chunk_t get_from_address(private_traffic_selector_t *this)
|
||||
{
|
||||
chunk_t from_addr = CHUNK_INITIALIZER;
|
||||
|
||||
switch (this->type)
|
||||
{
|
||||
case TS_IPV4_ADDR_RANGE:
|
||||
{
|
||||
u_int32_t network;
|
||||
from_addr.len = sizeof(network);
|
||||
from_addr.ptr = malloc(from_addr.len);
|
||||
/* chunk must contain network order, convert! */
|
||||
network = htonl(this->from_addr_ipv4);
|
||||
memcpy(from_addr.ptr, &network, from_addr.len);
|
||||
break;
|
||||
}
|
||||
case TS_IPV6_ADDR_RANGE:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return from_addr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements traffic_selector_t.get_to_address.
|
||||
*/
|
||||
static chunk_t get_to_address(private_traffic_selector_t *this)
|
||||
{
|
||||
chunk_t to_addr = CHUNK_INITIALIZER;
|
||||
|
||||
switch (this->type)
|
||||
{
|
||||
case TS_IPV4_ADDR_RANGE:
|
||||
{
|
||||
u_int32_t network;
|
||||
to_addr.len = sizeof(network);
|
||||
to_addr.ptr = malloc(to_addr.len);
|
||||
/* chunk must contain network order, convert! */
|
||||
network = htonl(this->to_addr_ipv4);
|
||||
memcpy(to_addr.ptr, &network, to_addr.len);
|
||||
break;
|
||||
}
|
||||
case TS_IPV6_ADDR_RANGE:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return to_addr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements traffic_selector_t.get_from_port.
|
||||
*/
|
||||
static u_int16_t get_from_port(private_traffic_selector_t *this)
|
||||
{
|
||||
return this->from_port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements traffic_selector_t.get_to_port.
|
||||
*/
|
||||
static u_int16_t get_to_port(private_traffic_selector_t *this)
|
||||
{
|
||||
return this->to_port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements traffic_selector_t.get_type.
|
||||
*/
|
||||
static ts_type_t get_type(private_traffic_selector_t *this)
|
||||
{
|
||||
return this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements traffic_selector_t.get_protocol.
|
||||
*/
|
||||
static u_int8_t get_protocol(private_traffic_selector_t *this)
|
||||
{
|
||||
return this->protocol;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements traffic_selector_t.get_netmask.
|
||||
*/
|
||||
static u_int8_t get_netmask(private_traffic_selector_t *this)
|
||||
{
|
||||
switch (this->type)
|
||||
{
|
||||
case TS_IPV4_ADDR_RANGE:
|
||||
{
|
||||
u_int32_t from, to, bit;
|
||||
from = htonl(this->from_addr_ipv4);
|
||||
to = htonl(this->to_addr_ipv4);
|
||||
for (bit = 0; bit < 32; bit++)
|
||||
{
|
||||
if ((1<<bit & from) != (1<<bit & to))
|
||||
{
|
||||
return bit;
|
||||
}
|
||||
}
|
||||
return 32;
|
||||
}
|
||||
case TS_IPV6_ADDR_RANGE:
|
||||
default:
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements traffic_selector_t.update_address_range.
|
||||
*/
|
||||
static void update_address_range(private_traffic_selector_t *this, host_t *host)
|
||||
{
|
||||
if (host->get_family(host) == AF_INET &&
|
||||
this->type == TS_IPV4_ADDR_RANGE)
|
||||
{
|
||||
if (this->from_addr_ipv4 == 0)
|
||||
{
|
||||
chunk_t from = host->get_address_as_chunk(host);
|
||||
this->from_addr_ipv4 = ntohl(*((u_int32_t*)from.ptr));
|
||||
this->to_addr_ipv4 = this->from_addr_ipv4;
|
||||
chunk_free(&from);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements traffic_selector_t.clone.
|
||||
*/
|
||||
static traffic_selector_t *clone(private_traffic_selector_t *this)
|
||||
{
|
||||
private_traffic_selector_t *clone = traffic_selector_create(this->protocol, this->type, this->from_port, this->to_port);
|
||||
clone->type = this->type;
|
||||
switch (clone->type)
|
||||
{
|
||||
case TS_IPV4_ADDR_RANGE:
|
||||
{
|
||||
clone->from_addr_ipv4 = this->from_addr_ipv4;
|
||||
clone->to_addr_ipv4 = this->to_addr_ipv4;
|
||||
return &(clone->public);
|
||||
}
|
||||
case TS_IPV6_ADDR_RANGE:
|
||||
default:
|
||||
{
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements traffic_selector_t.destroy.
|
||||
*/
|
||||
static void destroy(private_traffic_selector_t *this)
|
||||
{
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* see header
|
||||
*/
|
||||
traffic_selector_t *traffic_selector_create_from_bytes(u_int8_t protocol, ts_type_t type, chunk_t from_addr, int16_t from_port, chunk_t to_addr, u_int16_t to_port)
|
||||
{
|
||||
private_traffic_selector_t *this = traffic_selector_create(protocol, type, from_port, to_port);
|
||||
|
||||
this->type = type;
|
||||
switch (type)
|
||||
{
|
||||
case TS_IPV4_ADDR_RANGE:
|
||||
{
|
||||
if (from_addr.len != 4 || to_addr.len != 4)
|
||||
{
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
/* chunk contains network order, convert! */
|
||||
this->from_addr_ipv4 = ntohl(*((u_int32_t*)from_addr.ptr));
|
||||
this->to_addr_ipv4 = ntohl(*((u_int32_t*)to_addr.ptr));
|
||||
break;
|
||||
}
|
||||
case TS_IPV6_ADDR_RANGE:
|
||||
default:
|
||||
{
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return (&this->public);
|
||||
}
|
||||
|
||||
/*
|
||||
* see header
|
||||
*/
|
||||
traffic_selector_t *traffic_selector_create_from_subnet(host_t *net, u_int8_t netbits)
|
||||
{
|
||||
private_traffic_selector_t *this = traffic_selector_create(0, 0, 0, 65535);
|
||||
|
||||
switch (net->get_family(net))
|
||||
{
|
||||
case AF_INET:
|
||||
{
|
||||
chunk_t from;
|
||||
|
||||
this->type = TS_IPV4_ADDR_RANGE;
|
||||
from = net->get_address_as_chunk(net);
|
||||
this->from_addr_ipv4 = ntohl(*((u_int32_t*)from.ptr));
|
||||
if (this->from_addr_ipv4 == 0)
|
||||
{
|
||||
/* use /32 for 0.0.0.0 */
|
||||
this->to_addr_ipv4 = 0xFFFFFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->to_addr_ipv4 = this->from_addr_ipv4 | ((1 << (32 - netbits)) - 1);
|
||||
}
|
||||
chunk_free(&from);
|
||||
break;
|
||||
}
|
||||
case AF_INET6:
|
||||
default:
|
||||
{
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return (&this->public);
|
||||
}
|
||||
|
||||
/*
|
||||
* see header
|
||||
*/
|
||||
traffic_selector_t *traffic_selector_create_from_string(u_int8_t protocol, ts_type_t type, char *from_addr, u_int16_t from_port, char *to_addr, u_int16_t to_port)
|
||||
{
|
||||
private_traffic_selector_t *this = traffic_selector_create(protocol, type, from_port, to_port);
|
||||
|
||||
/* public functions */
|
||||
this->public.get_subset = (traffic_selector_t*(*)(traffic_selector_t*,traffic_selector_t*))get_subset;
|
||||
this->public.destroy = (void(*)(traffic_selector_t*))destroy;
|
||||
|
||||
this->type = type;
|
||||
switch (type)
|
||||
{
|
||||
case TS_IPV4_ADDR_RANGE:
|
||||
{
|
||||
if (inet_aton(from_addr, (struct in_addr*)&(this->from_addr_ipv4)) == 0)
|
||||
{
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
if (inet_aton(to_addr, (struct in_addr*)&(this->to_addr_ipv4)) == 0)
|
||||
{
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
/* convert to host order, inet_aton has network order */
|
||||
this->from_addr_ipv4 = ntohl(this->from_addr_ipv4);
|
||||
this->to_addr_ipv4 = ntohl(this->to_addr_ipv4);
|
||||
break;
|
||||
}
|
||||
case TS_IPV6_ADDR_RANGE:
|
||||
{
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return (&this->public);
|
||||
}
|
||||
|
||||
/*
|
||||
* see declaration
|
||||
*/
|
||||
static private_traffic_selector_t *traffic_selector_create(u_int8_t protocol, ts_type_t type, u_int16_t from_port, u_int16_t to_port)
|
||||
{
|
||||
private_traffic_selector_t *this = malloc_thing(private_traffic_selector_t);
|
||||
|
||||
/* public functions */
|
||||
this->public.get_subset = (traffic_selector_t*(*)(traffic_selector_t*,traffic_selector_t*))get_subset;
|
||||
this->public.get_from_address = (chunk_t(*)(traffic_selector_t*))get_from_address;
|
||||
this->public.get_to_address = (chunk_t(*)(traffic_selector_t*))get_to_address;
|
||||
this->public.get_from_port = (u_int16_t(*)(traffic_selector_t*))get_from_port;
|
||||
this->public.get_to_port = (u_int16_t(*)(traffic_selector_t*))get_to_port;
|
||||
this->public.get_type = (ts_type_t(*)(traffic_selector_t*))get_type;
|
||||
this->public.get_protocol = (u_int8_t(*)(traffic_selector_t*))get_protocol;
|
||||
this->public.get_netmask = (u_int8_t(*)(traffic_selector_t*))get_netmask;
|
||||
this->public.update_address_range = (void(*)(traffic_selector_t*,host_t*))update_address_range;
|
||||
this->public.clone = (traffic_selector_t*(*)(traffic_selector_t*))clone;
|
||||
this->public.destroy = (void(*)(traffic_selector_t*))destroy;
|
||||
|
||||
this->from_port = from_port;
|
||||
this->to_port = to_port;
|
||||
this->protocol = protocol;
|
||||
this->type = type;
|
||||
|
||||
return this;
|
||||
}
|
||||
@@ -0,0 +1,258 @@
|
||||
/**
|
||||
* @file traffic_selector.h
|
||||
*
|
||||
* @brief Interface of traffic_selector_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef TRAFFIC_SELECTOR_H_
|
||||
#define TRAFFIC_SELECTOR_H_
|
||||
|
||||
#include <types.h>
|
||||
#include <utils/host.h>
|
||||
|
||||
typedef enum ts_type_t ts_type_t;
|
||||
|
||||
/**
|
||||
* Traffic selector types.
|
||||
*
|
||||
* @ingroup config
|
||||
*/
|
||||
enum ts_type_t {
|
||||
|
||||
/**
|
||||
* A range of IPv4 addresses, represented by two four (4) octet
|
||||
* values. The first value is the beginning IPv4 address
|
||||
* (inclusive) and the second value is the ending IPv4 address
|
||||
* (inclusive). All addresses falling between the two specified
|
||||
* addresses are considered to be within the list.
|
||||
*/
|
||||
TS_IPV4_ADDR_RANGE = 7,
|
||||
|
||||
/**
|
||||
* A range of IPv6 addresses, represented by two sixteen (16)
|
||||
* octet values. The first value is the beginning IPv6 address
|
||||
* (inclusive) and the second value is the ending IPv6 address
|
||||
* (inclusive). All addresses falling between the two specified
|
||||
* addresses are considered to be within the list.
|
||||
*/
|
||||
TS_IPV6_ADDR_RANGE = 8
|
||||
};
|
||||
|
||||
/**
|
||||
* string mappings for ts_type_t
|
||||
*/
|
||||
extern mapping_t ts_type_m[];
|
||||
|
||||
|
||||
typedef struct traffic_selector_t traffic_selector_t;
|
||||
|
||||
/**
|
||||
* @brief Object representing a traffic selector entry.
|
||||
*
|
||||
* A traffic selector defines an range of addresses
|
||||
* and a range of ports. IPv6 is not fully supported yet.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - traffic_selector_create_from_bytes()
|
||||
* - traffic_selector_create_from_string()
|
||||
*
|
||||
* @todo Add IPv6 support
|
||||
*
|
||||
* @ingroup config
|
||||
*/
|
||||
struct traffic_selector_t {
|
||||
|
||||
/**
|
||||
* @brief Compare two traffic selectors, and create a new one
|
||||
* which is the largest subset of both (subnet & port).
|
||||
*
|
||||
* Resulting traffic_selector is newly created and must be destroyed.
|
||||
*
|
||||
* @param this first to compare
|
||||
* @param other second to compare
|
||||
* @return
|
||||
* - created subset of them
|
||||
* - or NULL if no match between this and other
|
||||
*/
|
||||
traffic_selector_t *(*get_subset) (traffic_selector_t *this, traffic_selector_t *other);
|
||||
|
||||
/**
|
||||
* @brief Clone a traffic selector.
|
||||
*
|
||||
* @param this traffic selector to clone
|
||||
* @return clone of it
|
||||
*/
|
||||
traffic_selector_t *(*clone) (traffic_selector_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get starting address of this ts as a chunk.
|
||||
*
|
||||
* Data is in network order and represents the address.
|
||||
* Size depends on protocol.
|
||||
*
|
||||
* Resulting chunk data is allocated and must be freed!
|
||||
*
|
||||
* @param this calling object
|
||||
* @return chunk containing the address
|
||||
*/
|
||||
chunk_t (*get_from_address) (traffic_selector_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get ending address of this ts as a chunk.
|
||||
*
|
||||
* Data is in network order and represents the address.
|
||||
* Size depends on protocol.
|
||||
*
|
||||
* Resulting chunk data is allocated and must be freed!
|
||||
*
|
||||
* @param this calling object
|
||||
* @return chunk containing the address
|
||||
*/
|
||||
chunk_t (*get_to_address) (traffic_selector_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get starting port of this ts.
|
||||
*
|
||||
* Port is in host order, since the parser converts it.
|
||||
* Size depends on protocol.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return port
|
||||
*/
|
||||
u_int16_t (*get_from_port) (traffic_selector_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get ending port of this ts.
|
||||
*
|
||||
* Port is in host order, since the parser converts it.
|
||||
* Size depends on protocol.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return port
|
||||
*/
|
||||
u_int16_t (*get_to_port) (traffic_selector_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get the type of the traffic selector.
|
||||
*
|
||||
* @param this calling obect
|
||||
* @return ts_type_t specifying the type
|
||||
*/
|
||||
ts_type_t (*get_type) (traffic_selector_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get the protocol id of this ts.
|
||||
*
|
||||
* @param this calling obect
|
||||
* @return protocol id
|
||||
*/
|
||||
u_int8_t (*get_protocol) (traffic_selector_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get the netmask of the address range.
|
||||
*
|
||||
* Returns the number of bits associated to the subnet.
|
||||
* (As the "24" in "192.168.0.0/24"). This is approximated
|
||||
* if the address range is not a complete subnet! Since Linux
|
||||
* does not support full IP address ranges (yet), we can't do this
|
||||
* (much) better.
|
||||
*
|
||||
* @param this calling obect
|
||||
* @return netmask as "bits for subnet"
|
||||
*/
|
||||
u_int8_t (*get_netmask) (traffic_selector_t *this);
|
||||
|
||||
/**
|
||||
* @brief Update the address of a traffic selector.
|
||||
*
|
||||
* Update the address range of a traffic selector,
|
||||
* if the current address is 0.0.0.0. The new address range
|
||||
* starts from the supplied address and also ends there
|
||||
* (which means it is a one-host-address-range ;-).
|
||||
*
|
||||
* @param this calling obect
|
||||
* @param host host_t specifying the address range
|
||||
*/
|
||||
void (*update_address_range) (traffic_selector_t *this, host_t* host);
|
||||
|
||||
/**
|
||||
* @brief Destroys the ts object
|
||||
*
|
||||
* @param this calling object
|
||||
*/
|
||||
void (*destroy) (traffic_selector_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Create a new traffic selector using human readable params.
|
||||
*
|
||||
* @param protocol protocol for this ts, such as TCP or UDP
|
||||
* @param type type of following addresses, such as TS_IPV4_ADDR_RANGE
|
||||
* @param from_addr start of address range as string
|
||||
* @param from_port port number in host order
|
||||
* @param to_addr end of address range as string
|
||||
* @param to_port port number in host order
|
||||
* @return
|
||||
* - traffic_selector_t object
|
||||
* - NULL if invalid address strings/protocol
|
||||
*
|
||||
* @ingroup config
|
||||
*/
|
||||
traffic_selector_t *traffic_selector_create_from_string(u_int8_t protocol, ts_type_t type, char *from_addr, u_int16_t from_port, char *to_addr, u_int16_t to_port);
|
||||
|
||||
/**
|
||||
* @brief Create a new traffic selector using data read from the net.
|
||||
*
|
||||
* There exists a mix of network and host order in the params.
|
||||
* But the parser gives us this data in this format, so we
|
||||
* don't have to convert twice.
|
||||
*
|
||||
* @param protocol protocol for this ts, such as TCP or UDP
|
||||
* @param type type of following addresses, such as TS_IPV4_ADDR_RANGE
|
||||
* @param from_address start of address range, network order
|
||||
* @param from_port port number, host order
|
||||
* @param to_address end of address range as string, network
|
||||
* @param to_port port number, host order
|
||||
* @return
|
||||
* - traffic_selector_t object
|
||||
* - NULL if invalid address input/protocol
|
||||
*
|
||||
* @ingroup config
|
||||
*/
|
||||
traffic_selector_t *traffic_selector_create_from_bytes(u_int8_t protocol, ts_type_t type, chunk_t from_address, int16_t from_port, chunk_t to_address, u_int16_t to_port);
|
||||
|
||||
/**
|
||||
* @brief Create a new traffic selector defining a whole subnet.
|
||||
*
|
||||
* In most cases, definition of a traffic selector for full subnets
|
||||
* is sufficient. This constructor creates a traffic selector for
|
||||
* all protocols, all ports and the address range specified by the
|
||||
* subnet.
|
||||
*
|
||||
* @param net subnet to use
|
||||
* @param netbits size of the subnet, as used in e.g. 192.168.0.0/24 notation
|
||||
* @return
|
||||
* - traffic_selector_t object
|
||||
* - NULL if address family of net not supported
|
||||
*
|
||||
* @ingroup config
|
||||
*/
|
||||
traffic_selector_t *traffic_selector_create_from_subnet(host_t *net, u_int8_t netbits);
|
||||
|
||||
#endif /* TRAFFIC_SELECTOR_H_ */
|
||||
@@ -0,0 +1,390 @@
|
||||
/**
|
||||
* @file daemon.c
|
||||
*
|
||||
* @brief Implementation of daemon_t and main of IKEv2-Daemon.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <execinfo.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "daemon.h"
|
||||
|
||||
#include <types.h>
|
||||
#include <config/connections/local_connection_store.h>
|
||||
#include <config/credentials/local_credential_store.h>
|
||||
#include <config/policies/local_policy_store.h>
|
||||
|
||||
|
||||
typedef struct private_daemon_t private_daemon_t;
|
||||
|
||||
/**
|
||||
* Private additions to daemon_t, contains threads and internal functions.
|
||||
*/
|
||||
struct private_daemon_t {
|
||||
/**
|
||||
* Public members of daemon_t.
|
||||
*/
|
||||
daemon_t public;
|
||||
|
||||
/**
|
||||
* A logger_t object assigned for daemon things.
|
||||
*/
|
||||
logger_t *logger;
|
||||
|
||||
/**
|
||||
* Signal set used for signal handling.
|
||||
*/
|
||||
sigset_t signal_set;
|
||||
|
||||
/**
|
||||
* The thread_id of main-thread.
|
||||
*/
|
||||
pthread_t main_thread_id;
|
||||
|
||||
/**
|
||||
* Main loop function.
|
||||
*
|
||||
* @param this calling object
|
||||
*/
|
||||
void (*run) (private_daemon_t *this);
|
||||
|
||||
/**
|
||||
* Initialize the daemon.
|
||||
*
|
||||
* @param this calling object
|
||||
*/
|
||||
void (*initialize) (private_daemon_t *this);
|
||||
|
||||
/**
|
||||
* Destroy the daemon.
|
||||
*
|
||||
* @param this calling object
|
||||
*/
|
||||
void (*destroy) (private_daemon_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* One and only instance of the daemon.
|
||||
*/
|
||||
daemon_t *charon;
|
||||
|
||||
/**
|
||||
* Implementation of private_daemon_t.run.
|
||||
*/
|
||||
static void run(private_daemon_t *this)
|
||||
{
|
||||
/* reselect signals for this thread */
|
||||
sigemptyset(&(this->signal_set));
|
||||
sigaddset(&(this->signal_set), SIGINT);
|
||||
sigaddset(&(this->signal_set), SIGHUP);
|
||||
sigaddset(&(this->signal_set), SIGTERM);
|
||||
pthread_sigmask(SIG_BLOCK, &(this->signal_set), 0);
|
||||
|
||||
while(TRUE)
|
||||
{
|
||||
int signal_number;
|
||||
int error;
|
||||
|
||||
error = sigwait(&(this->signal_set), &signal_number);
|
||||
if(error)
|
||||
{
|
||||
this->logger->log(this->logger, ERROR, "Error %d when waiting for signal", error);
|
||||
return;
|
||||
}
|
||||
switch (signal_number)
|
||||
{
|
||||
case SIGHUP:
|
||||
{
|
||||
this->logger->log(this->logger, CONTROL, "Signal of type SIGHUP received. Do nothing");
|
||||
break;
|
||||
}
|
||||
case SIGINT:
|
||||
{
|
||||
this->logger->log(this->logger, CONTROL, "Signal of type SIGINT received. Exit main loop");
|
||||
return;
|
||||
}
|
||||
case SIGTERM:
|
||||
this->logger->log(this->logger, CONTROL, "Signal of type SIGTERM received. Exit main loop");
|
||||
return;
|
||||
default:
|
||||
{
|
||||
this->logger->log(this->logger, CONTROL, "Unknown signal %d received. Do nothing", signal_number);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of daemon_t.kill.
|
||||
*/
|
||||
static void kill_daemon(private_daemon_t *this, char *reason)
|
||||
{
|
||||
/* we send SIGTERM, so the daemon can cleanly shut down */
|
||||
this->logger->log(this->logger, CONTROL, "Killing daemon: %s", reason);
|
||||
if (this->main_thread_id == pthread_self())
|
||||
{
|
||||
/* initialization failed, terminate daemon */
|
||||
this->destroy(this);
|
||||
unlink(PID_FILE);
|
||||
exit(-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->logger->log(this->logger, CONTROL, "sending SIGTERM to ourself", reason);
|
||||
kill(0, SIGTERM);
|
||||
/* thread must die, since he produced a ciritcal failure and can't continue */
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of private_daemon_t.initialize.
|
||||
*/
|
||||
static void initialize(private_daemon_t *this)
|
||||
{
|
||||
local_credential_store_t* cred_store;
|
||||
|
||||
this->public.configuration = configuration_create();
|
||||
this->public.socket = socket_create(IKEV2_UDP_PORT);
|
||||
this->public.ike_sa_manager = ike_sa_manager_create();
|
||||
this->public.job_queue = job_queue_create();
|
||||
this->public.event_queue = event_queue_create();
|
||||
this->public.send_queue = send_queue_create();
|
||||
this->public.connections = (connection_store_t*)local_connection_store_create();
|
||||
this->public.policies = (policy_store_t*)local_policy_store_create();
|
||||
this->public.credentials = (credential_store_t*)(cred_store = local_credential_store_create());
|
||||
|
||||
/* load keys & certs */
|
||||
cred_store->load_certificates(cred_store, CERTIFICATE_DIR);
|
||||
cred_store->load_private_keys(cred_store, PRIVATE_KEY_DIR);
|
||||
|
||||
|
||||
/* start building threads, we are multi-threaded NOW */
|
||||
this->public.stroke = stroke_create();
|
||||
this->public.sender = sender_create();
|
||||
this->public.receiver = receiver_create();
|
||||
this->public.scheduler = scheduler_create();
|
||||
this->public.kernel_interface = kernel_interface_create();
|
||||
this->public.thread_pool = thread_pool_create(NUMBER_OF_WORKING_THREADS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destory all initiated objects
|
||||
*/
|
||||
static void destroy(private_daemon_t *this)
|
||||
{
|
||||
if (this->public.ike_sa_manager != NULL)
|
||||
{
|
||||
this->public.ike_sa_manager->destroy(this->public.ike_sa_manager);
|
||||
}
|
||||
if (this->public.kernel_interface != NULL)
|
||||
{
|
||||
this->public.kernel_interface->destroy(this->public.kernel_interface);
|
||||
}
|
||||
if (this->public.receiver != NULL)
|
||||
{
|
||||
this->public.receiver->destroy(this->public.receiver);
|
||||
}
|
||||
if (this->public.scheduler != NULL)
|
||||
{
|
||||
this->public.scheduler->destroy(this->public.scheduler);
|
||||
}
|
||||
if (this->public.sender != NULL)
|
||||
{
|
||||
this->public.sender->destroy(this->public.sender);
|
||||
}
|
||||
if (this->public.thread_pool != NULL)
|
||||
{
|
||||
this->public.thread_pool->destroy(this->public.thread_pool);
|
||||
}
|
||||
if (this->public.job_queue != NULL)
|
||||
{
|
||||
this->public.job_queue->destroy(this->public.job_queue);
|
||||
}
|
||||
if (this->public.event_queue != NULL)
|
||||
{
|
||||
this->public.event_queue->destroy(this->public.event_queue);
|
||||
}
|
||||
if (this->public.send_queue != NULL)
|
||||
{
|
||||
this->public.send_queue->destroy(this->public.send_queue);
|
||||
}
|
||||
if (this->public.socket != NULL)
|
||||
{
|
||||
this->public.socket->destroy(this->public.socket);
|
||||
}
|
||||
if (this->public.configuration != NULL)
|
||||
{
|
||||
this->public.configuration->destroy(this->public.configuration);
|
||||
}
|
||||
if (this->public.credentials != NULL)
|
||||
{
|
||||
this->public.credentials->destroy(this->public.credentials);
|
||||
}
|
||||
if (this->public.connections != NULL)
|
||||
{
|
||||
this->public.connections->destroy(this->public.connections);
|
||||
}
|
||||
if (this->public.policies != NULL)
|
||||
{
|
||||
this->public.policies->destroy(this->public.policies);
|
||||
}
|
||||
if (this->public.stroke != NULL)
|
||||
{
|
||||
this->public.stroke->destroy(this->public.stroke);
|
||||
}
|
||||
free(this);
|
||||
}
|
||||
|
||||
void signal_handler(int signal)
|
||||
{
|
||||
void *array[20];
|
||||
size_t size;
|
||||
char **strings;
|
||||
size_t i;
|
||||
logger_t *logger;
|
||||
|
||||
size = backtrace(array, 20);
|
||||
strings = backtrace_symbols(array, size);
|
||||
logger = logger_manager->get_logger(logger_manager, DAEMON);
|
||||
|
||||
logger->log(logger, ERROR, "Thread %u received SIGSEGV. Dumping %d frames from stack:", pthread_self(), size);
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
logger->log(logger, ERROR, " %s", strings[i]);
|
||||
}
|
||||
free (strings);
|
||||
logger->log(logger, ERROR, "Killing ourself hard after SIGSEGV");
|
||||
kill(getpid(), SIGKILL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create the daemon.
|
||||
*
|
||||
* @return created daemon_t
|
||||
*/
|
||||
private_daemon_t *daemon_create()
|
||||
{
|
||||
private_daemon_t *this = malloc_thing(private_daemon_t);
|
||||
struct sigaction action;
|
||||
|
||||
/* assign methods */
|
||||
this->run = run;
|
||||
this->destroy = destroy;
|
||||
this->initialize = initialize;
|
||||
this->public.kill = (void (*) (daemon_t*,char*))kill_daemon;
|
||||
|
||||
/* NULL members for clean destruction */
|
||||
this->public.socket = NULL;
|
||||
this->public.ike_sa_manager = NULL;
|
||||
this->public.job_queue = NULL;
|
||||
this->public.event_queue = NULL;
|
||||
this->public.send_queue = NULL;
|
||||
this->public.configuration = NULL;
|
||||
this->public.credentials = NULL;
|
||||
this->public.connections = NULL;
|
||||
this->public.policies = NULL;
|
||||
this->public.sender= NULL;
|
||||
this->public.receiver = NULL;
|
||||
this->public.scheduler = NULL;
|
||||
this->public.kernel_interface = NULL;
|
||||
this->public.thread_pool = NULL;
|
||||
this->public.stroke = NULL;
|
||||
|
||||
this->main_thread_id = pthread_self();
|
||||
|
||||
/* setup signal handling for all threads */
|
||||
sigemptyset(&(this->signal_set));
|
||||
sigaddset(&(this->signal_set), SIGSEGV);
|
||||
sigaddset(&(this->signal_set), SIGINT);
|
||||
sigaddset(&(this->signal_set), SIGHUP);
|
||||
sigaddset(&(this->signal_set), SIGTERM);
|
||||
pthread_sigmask(SIG_BLOCK, &(this->signal_set), 0);
|
||||
|
||||
/* setup SIGSEGV handler for all threads */
|
||||
action.sa_handler = signal_handler;
|
||||
action.sa_mask = this->signal_set;
|
||||
action.sa_flags = 0;
|
||||
if (sigaction(SIGSEGV, &action, NULL) == -1)
|
||||
{
|
||||
this->logger->log(this->logger, ERROR, "signal handler setup for SIGSEGV failed");
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main function, manages the daemon.
|
||||
*/
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
private_daemon_t *private_charon;
|
||||
FILE *pid_file;
|
||||
struct stat stb;
|
||||
int i;
|
||||
|
||||
/* trivial argument parsing */
|
||||
for (i = 1; i < argc; i++)
|
||||
{
|
||||
if (strcmp(argv[i], "--use-syslog") == 0)
|
||||
{
|
||||
logger_manager->set_output(logger_manager, ALL_LOGGERS, NULL);
|
||||
}
|
||||
}
|
||||
private_charon = daemon_create();
|
||||
charon = (daemon_t*)private_charon;
|
||||
|
||||
private_charon->logger = logger_manager->get_logger(logger_manager, DAEMON);
|
||||
|
||||
/* initialize daemon */
|
||||
private_charon->initialize(private_charon);
|
||||
|
||||
/* check/setup PID file */
|
||||
if (stat(PID_FILE, &stb) == 0)
|
||||
{
|
||||
private_charon->logger->log(private_charon->logger, ERROR,
|
||||
"charon already running (\""PID_FILE"\" exists)");
|
||||
private_charon->destroy(private_charon);
|
||||
exit(-1);
|
||||
}
|
||||
pid_file = fopen(PID_FILE, "w");
|
||||
if (pid_file)
|
||||
{
|
||||
fprintf(pid_file, "%d\n", getpid());
|
||||
fclose(pid_file);
|
||||
}
|
||||
|
||||
/* run daemon */
|
||||
private_charon->run(private_charon);
|
||||
|
||||
/* normal termination, cleanup and exit */
|
||||
private_charon->destroy(private_charon);
|
||||
unlink(PID_FILE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,324 @@
|
||||
/**
|
||||
* @file daemon.h
|
||||
*
|
||||
* @brief Interface of daemon_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef DAEMON_H_
|
||||
#define DAEMON_H_
|
||||
|
||||
#include <threads/sender.h>
|
||||
#include <threads/receiver.h>
|
||||
#include <threads/scheduler.h>
|
||||
#include <threads/kernel_interface.h>
|
||||
#include <threads/thread_pool.h>
|
||||
#include <threads/stroke_interface.h>
|
||||
#include <network/socket.h>
|
||||
#include <sa/ike_sa_manager.h>
|
||||
#include <queues/send_queue.h>
|
||||
#include <queues/job_queue.h>
|
||||
#include <queues/event_queue.h>
|
||||
#include <utils/logger_manager.h>
|
||||
#include <config/configuration.h>
|
||||
#include <config/connections/connection_store.h>
|
||||
#include <config/policies/policy_store.h>
|
||||
#include <config/credentials/credential_store.h>
|
||||
|
||||
/**
|
||||
* @defgroup charon charon
|
||||
*
|
||||
* @brief IKEv2 keying daemon.
|
||||
*
|
||||
* @section Architecture
|
||||
*
|
||||
* All IKEv2 stuff is handled in charon. It uses a newer and more flexible
|
||||
* architecture than pluto. Charon uses a thread-pool, which allows parallel
|
||||
* execution SA-management. Beside the thread-pool, there are some special purpose
|
||||
* threads which do their job for the common health of the daemon.
|
||||
@verbatim
|
||||
+------+
|
||||
| E Q |
|
||||
| v u |---+ +------+ +------+
|
||||
| e e | | | | | IKE- |
|
||||
| n u | +-----------+ | |--| SA |
|
||||
| t e | | | | I M | +------+
|
||||
+------------+ | - | | Scheduler | | K a |
|
||||
| receiver | +------+ | | | E n | +------+
|
||||
+----+-------+ +-----------+ | - a | | IKE- |
|
||||
| | +------+ | | S g |--| SA |
|
||||
+-------+--+ +-----| J Q |---+ +------------+ | A e | +------+
|
||||
-| socket | | o u | | | | - r |
|
||||
+-------+--+ | b e | | Thread- | | |
|
||||
| | - u | | Pool | | |
|
||||
+----+-------+ | e |------| |---| |
|
||||
| sender | +------+ +------------+ +------+
|
||||
+----+-------+
|
||||
| +------+
|
||||
| | S Q |
|
||||
| | e u |
|
||||
| | n e |
|
||||
+------------| d u |
|
||||
| - e |
|
||||
+--+---+
|
||||
@endverbatim
|
||||
* The thread-pool is the heart of the architecture. It processes jobs from a
|
||||
* (fully synchronized) job-queue. Mostly, a job is associated with a specific
|
||||
* IKE SA. These IKE SAs are synchronized, only one thread can work one an IKE SA.
|
||||
* This makes it unnecesary to use further synchronisation methods once a IKE SA
|
||||
* is checked out. The (rather complex) synchronization of IKE SAs is completely
|
||||
* done in the IKE SA manager.
|
||||
* The sceduler is responsible for event firing. It waits until a event in the
|
||||
* (fully synchronized) event-queue is ready for processing and pushes the event
|
||||
* down to the job-queue. A thread form the pool will pick it up as quick as
|
||||
* possible. Every thread can queue events or jobs. Furter, an event can place a
|
||||
* packet in the send-queue. The sender thread waits for those packets and sends
|
||||
* them over the wire, via the socket. The receiver does exactly the opposite of
|
||||
* the sender. It waits on the socket, reads in packets an places them on the
|
||||
* job-queue for further processing by a thread from the pool.
|
||||
* There are even more threads, not drawn in the upper scheme. The stroke thread
|
||||
* is responsible for reading and processessing commands from another process. The
|
||||
* kernel interface thread handles communication from and to the kernel via a
|
||||
* netlink socket. It waits for kernel events and processes them appropriately.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup config config
|
||||
*
|
||||
* Classes implementing configuration related things.
|
||||
*
|
||||
* @ingroup charon
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup encoding encoding
|
||||
*
|
||||
* Classes used to encode and decode IKEv2 messages.
|
||||
*
|
||||
* @ingroup charon
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup payloads payloads
|
||||
*
|
||||
* Classes representing specific IKEv2 payloads.
|
||||
*
|
||||
* @ingroup encoding
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup network network
|
||||
*
|
||||
* Classes for network relevant stuff.
|
||||
*
|
||||
* @ingroup charon
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup queues queues
|
||||
*
|
||||
* Different kind of queues
|
||||
* (thread save lists).
|
||||
*
|
||||
* @ingroup charon
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup jobs jobs
|
||||
*
|
||||
* Jobs used in job queue and event queue.
|
||||
*
|
||||
* @ingroup queues
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup sa sa
|
||||
*
|
||||
* Security associations for IKE and IPSec,
|
||||
* and some helper classes.
|
||||
*
|
||||
* @ingroup charon
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup states states
|
||||
*
|
||||
* Varius states in which an IKE SA can be.
|
||||
*
|
||||
* @ingroup sa
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup threads threads
|
||||
*
|
||||
* Threaded classes, which will do their job alone.
|
||||
*
|
||||
* @ingroup charon
|
||||
*/
|
||||
|
||||
/**
|
||||
* Name of the daemon.
|
||||
*
|
||||
* @ingroup charon
|
||||
*/
|
||||
#define DAEMON_NAME "charon"
|
||||
|
||||
/**
|
||||
* @brief Number of threads in the thread pool.
|
||||
*
|
||||
* There are several other threads, this defines
|
||||
* only the number of threads in thread_pool_t.
|
||||
*
|
||||
* @ingroup charon
|
||||
*/
|
||||
#define NUMBER_OF_WORKING_THREADS 4
|
||||
|
||||
/**
|
||||
* UDP Port on which the daemon will listen for incoming traffic.
|
||||
*
|
||||
* @ingroup charon
|
||||
*/
|
||||
#define IKEV2_UDP_PORT 500
|
||||
|
||||
/**
|
||||
* PID file, in which charon stores its process id
|
||||
*
|
||||
* @ingroup charon
|
||||
*/
|
||||
#define PID_FILE "/var/run/charon.pid"
|
||||
|
||||
/**
|
||||
* Directory of IPsec relevant files
|
||||
*
|
||||
* @ingroup charon
|
||||
*/
|
||||
#define IPSEC_DIR "/etc/ipsec.d"
|
||||
|
||||
/**
|
||||
* Directory for private keys
|
||||
*
|
||||
* @ingroup charon
|
||||
*/
|
||||
#define PRIVATE_KEY_DIR IPSEC_DIR "/private"
|
||||
|
||||
/**
|
||||
* Directory for trusted certificates
|
||||
*
|
||||
* @ingroup charon
|
||||
*/
|
||||
#define CERTIFICATE_DIR IPSEC_DIR "/certs"
|
||||
|
||||
|
||||
typedef struct daemon_t daemon_t;
|
||||
|
||||
/**
|
||||
* @brief Main class of daemon, contains some globals.
|
||||
*
|
||||
* @ingroup charon
|
||||
*/
|
||||
struct daemon_t {
|
||||
/**
|
||||
* A socket_t instance.
|
||||
*/
|
||||
socket_t *socket;
|
||||
|
||||
/**
|
||||
* A send_queue_t instance.
|
||||
*/
|
||||
send_queue_t *send_queue;
|
||||
|
||||
/**
|
||||
* A job_queue_t instance.
|
||||
*/
|
||||
job_queue_t *job_queue;
|
||||
|
||||
/**
|
||||
* A event_queue_t instance.
|
||||
*/
|
||||
event_queue_t *event_queue;
|
||||
|
||||
/**
|
||||
* A ike_sa_manager_t instance.
|
||||
*/
|
||||
ike_sa_manager_t *ike_sa_manager;
|
||||
|
||||
/**
|
||||
* A configuration_t instance.
|
||||
*/
|
||||
configuration_t *configuration;
|
||||
|
||||
/**
|
||||
* A connection_store_t instance.
|
||||
*/
|
||||
connection_store_t *connections;
|
||||
|
||||
/**
|
||||
* A policy_store_t instance.
|
||||
*/
|
||||
policy_store_t *policies;
|
||||
|
||||
/**
|
||||
* A credential_store_t instance.
|
||||
*/
|
||||
credential_store_t *credentials;
|
||||
|
||||
/**
|
||||
* The Sender-Thread.
|
||||
*/
|
||||
sender_t *sender;
|
||||
|
||||
/**
|
||||
* The Receiver-Thread.
|
||||
*/
|
||||
receiver_t *receiver;
|
||||
|
||||
/**
|
||||
* The Scheduler-Thread.
|
||||
*/
|
||||
scheduler_t *scheduler;
|
||||
|
||||
/**
|
||||
* The Thread pool managing the worker threads.
|
||||
*/
|
||||
thread_pool_t *thread_pool;
|
||||
|
||||
/**
|
||||
* Kernel Interface to communicate with kernel
|
||||
*/
|
||||
kernel_interface_t *kernel_interface;
|
||||
|
||||
/**
|
||||
* IPC interface, as whack in pluto
|
||||
*/
|
||||
stroke_t *stroke;
|
||||
|
||||
/**
|
||||
* @brief Shut down the daemon.
|
||||
*
|
||||
* @param this the daemon to kill
|
||||
* @param reason describtion why it will be killed
|
||||
*/
|
||||
void (*kill) (daemon_t *this, char *reason);
|
||||
};
|
||||
|
||||
/**
|
||||
* The one and only instance of the daemon.
|
||||
*/
|
||||
extern daemon_t *charon;
|
||||
|
||||
#endif /*DAEMON_H_*/
|
||||
@@ -0,0 +1,30 @@
|
||||
# Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
# Hochschule fuer Technik Rapperswil
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the
|
||||
# Free Software Foundation; either version 2 of the License, or (at your
|
||||
# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# for more details.
|
||||
#
|
||||
|
||||
ENCODING_DIR= $(CHARON_DIR)encoding/
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)generator.o
|
||||
$(BUILD_DIR)generator.o : $(ENCODING_DIR)generator.c $(ENCODING_DIR)generator.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)parser.o
|
||||
$(BUILD_DIR)parser.o : $(ENCODING_DIR)parser.c $(ENCODING_DIR)parser.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)message.o
|
||||
$(BUILD_DIR)message.o : $(ENCODING_DIR)message.c $(ENCODING_DIR)message.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
|
||||
include $(ENCODING_DIR)payloads/Makefile.payloads
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,101 @@
|
||||
/**
|
||||
* @file generator.h
|
||||
*
|
||||
* @brief Interface of generator_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef GENERATOR_H_
|
||||
#define GENERATOR_H_
|
||||
|
||||
#include <types.h>
|
||||
#include <encoding/payloads/encodings.h>
|
||||
#include <encoding/payloads/payload.h>
|
||||
|
||||
/**
|
||||
* Generating is done in a data buffer.
|
||||
* This is thehe start size of this buffer in bytes.
|
||||
*
|
||||
* @ingroup enconding
|
||||
*/
|
||||
#define GENERATOR_DATA_BUFFER_SIZE 500
|
||||
|
||||
/**
|
||||
* Number of bytes to increase the buffer, if it is to small.
|
||||
*
|
||||
* @ingroup enconding
|
||||
*/
|
||||
#define GENERATOR_DATA_BUFFER_INCREASE_VALUE 500
|
||||
|
||||
|
||||
typedef struct generator_t generator_t;
|
||||
|
||||
/**
|
||||
* @brief A generator_t class used to generate IKEv2 payloads.
|
||||
*
|
||||
* After creation, multiple payloads can be generated with the generate_payload
|
||||
* method. The generated bytes are appended. After all payloads are added,
|
||||
* the write_to_chunk method writes out all generated data since
|
||||
* the creation of the generator. After that, the generator must be destroyed.
|
||||
* The generater uses a set of encoding rules, which it can get from
|
||||
* the supplied payload. With this rules, the generater can generate
|
||||
* the payload and all substructures automatically.
|
||||
*
|
||||
* @b Constructor:
|
||||
* - generator_create()
|
||||
*
|
||||
* @ingroup encoding
|
||||
*/
|
||||
struct generator_t {
|
||||
|
||||
/**
|
||||
* @brief Generates a specific payload from given payload object.
|
||||
*
|
||||
* Remember: Header and substructures are also handled as payloads.
|
||||
*
|
||||
* @param this generator_t object
|
||||
* @param[in] payload interface payload_t implementing object
|
||||
*/
|
||||
void (*generate_payload) (generator_t *this,payload_t *payload);
|
||||
|
||||
/**
|
||||
* @brief Writes all generated data of the generator to a chunk.
|
||||
*
|
||||
* @param this generator_t object
|
||||
* @param[out] data chunk to write the data to
|
||||
*/
|
||||
void (*write_to_chunk) (generator_t *this,chunk_t *data);
|
||||
|
||||
/**
|
||||
* @brief Destroys a generator_t object.
|
||||
*
|
||||
* @param this generator_t object
|
||||
*/
|
||||
void (*destroy) (generator_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Constructor to create a generator.
|
||||
*
|
||||
* @return generator_t object.
|
||||
*
|
||||
* @ingroup encoding
|
||||
*/
|
||||
generator_t *generator_create();
|
||||
|
||||
#endif /*GENERATOR_H_*/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,367 @@
|
||||
/**
|
||||
* @file message.h
|
||||
*
|
||||
* @brief Interface of message_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef MESSAGE_H_
|
||||
#define MESSAGE_H_
|
||||
|
||||
#include <types.h>
|
||||
#include <sa/ike_sa_id.h>
|
||||
#include <network/packet.h>
|
||||
#include <encoding/payloads/ike_header.h>
|
||||
#include <encoding/payloads/notify_payload.h>
|
||||
#include <utils/linked_list.h>
|
||||
#include <crypto/crypters/crypter.h>
|
||||
#include <crypto/signers/signer.h>
|
||||
|
||||
|
||||
typedef struct message_t message_t;
|
||||
|
||||
/**
|
||||
* @brief This class is used to represent an IKEv2-Message.
|
||||
*
|
||||
* The message handles parsing and generation of payloads
|
||||
* via parser_t/generator_t. Encryption is done transparently
|
||||
* via the encryption_payload_t. A set of rules for messages
|
||||
* and payloads does check parsed messages.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - message_create()
|
||||
* - message_create_from_packet()
|
||||
* - message_create_notify_reply()
|
||||
*
|
||||
* @ingroup encoding
|
||||
*/
|
||||
struct message_t {
|
||||
|
||||
/**
|
||||
* @brief Sets the IKE major version of the message.
|
||||
*
|
||||
* @param this message_t object
|
||||
* @param major_version major version to set
|
||||
*/
|
||||
void (*set_major_version) (message_t *this,u_int8_t major_version);
|
||||
|
||||
/**
|
||||
* @brief Gets the IKE major version of the message.
|
||||
*
|
||||
* @param this message_t object
|
||||
* @return major version of the message
|
||||
*/
|
||||
u_int8_t (*get_major_version) (message_t *this);
|
||||
|
||||
/**
|
||||
* @brief Sets the IKE minor version of the message.
|
||||
*
|
||||
* @param this message_t object
|
||||
* @param minor_version minor version to set
|
||||
*/
|
||||
void (*set_minor_version) (message_t *this,u_int8_t minor_version);
|
||||
|
||||
/**
|
||||
* @brief Gets the IKE minor version of the message.
|
||||
*
|
||||
* @param this message_t object
|
||||
* @return minor version of the message
|
||||
*/
|
||||
u_int8_t (*get_minor_version) (message_t *this);
|
||||
|
||||
/**
|
||||
* @brief Sets the Message ID of the message.
|
||||
*
|
||||
* @param this message_t object
|
||||
* @param message_id message_id to set
|
||||
*/
|
||||
void (*set_message_id) (message_t *this,u_int32_t message_id);
|
||||
|
||||
/**
|
||||
* @brief Gets the Message ID of the message.
|
||||
*
|
||||
* @param this message_t object
|
||||
* @return message_id type of the message
|
||||
*/
|
||||
u_int32_t (*get_message_id) (message_t *this);
|
||||
|
||||
/**
|
||||
* @brief Gets the responder SPI of the message.
|
||||
*
|
||||
* @param this message_t object
|
||||
* @return responder spi of the message
|
||||
*/
|
||||
u_int64_t (*get_responder_spi) (message_t *this);
|
||||
|
||||
/**
|
||||
* @brief Sets the IKE_SA ID of the message.
|
||||
*
|
||||
* @warning ike_sa_id gets cloned internaly and
|
||||
* so can be destroyed afterwards.
|
||||
*
|
||||
* @param this message_t object
|
||||
* @param ike_sa_id ike_sa_id to set
|
||||
*/
|
||||
void (*set_ike_sa_id) (message_t *this,ike_sa_id_t * ike_sa_id);
|
||||
|
||||
/**
|
||||
* @brief Gets the IKE_SA ID of the message.
|
||||
*
|
||||
* @warning The returned ike_sa_id is a clone of the internal one.
|
||||
* So it has to be destroyed by the caller.
|
||||
*
|
||||
* @param this message_t object
|
||||
* @param ike_sa_id pointer to ike_sa_id pointer which will be set
|
||||
* @return
|
||||
* - SUCCESS
|
||||
* - FAILED if no ike_sa_id is set
|
||||
*/
|
||||
status_t (*get_ike_sa_id) (message_t *this,ike_sa_id_t **ike_sa_id);
|
||||
|
||||
/**
|
||||
* @brief Sets the exchange type of the message.
|
||||
*
|
||||
* @param this message_t object
|
||||
* @param exchange_type exchange_type to set
|
||||
*/
|
||||
void (*set_exchange_type) (message_t *this,exchange_type_t exchange_type);
|
||||
|
||||
/**
|
||||
* @brief Gets the exchange type of the message.
|
||||
*
|
||||
* @param this message_t object
|
||||
* @return exchange type of the message
|
||||
*/
|
||||
exchange_type_t (*get_exchange_type) (message_t *this);
|
||||
|
||||
/**
|
||||
* @brief Sets the request flag.
|
||||
*
|
||||
* @param this message_t object
|
||||
* @param original_initiator TRUE if message is a request, FALSE if it is a reply
|
||||
*/
|
||||
void (*set_request) (message_t *this,bool request);
|
||||
|
||||
/**
|
||||
* @brief Gets request flag.
|
||||
*
|
||||
* @param this message_t object
|
||||
* @return TRUE if message is a request, FALSE if it is a reply
|
||||
*/
|
||||
bool (*get_request) (message_t *this);
|
||||
|
||||
/**
|
||||
* @brief Append a payload to the message.
|
||||
*
|
||||
* If the payload must be encrypted is not specified here. Encryption
|
||||
* of payloads is evaluated via internal rules for the messages and
|
||||
* is done before generation. The order of payloads may change, since
|
||||
* all payloads to encrypt are added to the encryption payload, which is
|
||||
* always the last one.
|
||||
*
|
||||
* @param this message_t object
|
||||
* @param payload payload to append
|
||||
*/
|
||||
void (*add_payload) (message_t *this, payload_t *payload);
|
||||
|
||||
/**
|
||||
* @brief Parses header of message.
|
||||
*
|
||||
* Begins parisng of a message created via message_create_from_packet().
|
||||
* The parsing context is stored, so a subsequent call to parse_body()
|
||||
* will continue the parsing process.
|
||||
*
|
||||
* @param this message_t object
|
||||
* @return
|
||||
* - SUCCESS if header could be parsed
|
||||
* - PARSE_ERROR if corrupted/invalid data found
|
||||
* - FAILED if consistence check of header failed
|
||||
*/
|
||||
status_t (*parse_header) (message_t *this);
|
||||
|
||||
/**
|
||||
* @brief Parses body of message.
|
||||
*
|
||||
* The body gets not only parsed, but rather it gets verified.
|
||||
* All payloads are verified if they are allowed to exist in the message
|
||||
* of this type and if their own structure is ok.
|
||||
* If there are encrypted payloads, they get decrypted via the supplied
|
||||
* crypter. Also the message integrity gets verified with the supplied
|
||||
* signer.
|
||||
* Crypter/signer can be omitted (by passing NULL) when no encryption
|
||||
* payload is expected.
|
||||
*
|
||||
* @param this message_t object
|
||||
* @param crypter crypter to decrypt encryption payloads
|
||||
* @param signer signer to verifiy a message with an encryption payload
|
||||
* @return
|
||||
* - SUCCESS if header could be parsed
|
||||
* - NOT_SUPPORTED if ciritcal unknown payloads found
|
||||
* - FAILED if message type is not suppported!
|
||||
* - PARSE_ERROR if corrupted/invalid data found
|
||||
* - VERIFY_ERROR if verification of some payload failed
|
||||
* - INVALID_STATE if crypter/signer not supplied, but needed
|
||||
*/
|
||||
status_t (*parse_body) (message_t *this, crypter_t *crypter, signer_t *signer);
|
||||
|
||||
/**
|
||||
* @brief Generates the UDP packet of specific message.
|
||||
*
|
||||
* Payloads which must be encrypted are generated first and added to
|
||||
* an encryption payload. This encryption payload will get encrypted via
|
||||
* the supplied crypter. Then all other payloads and the header get generated.
|
||||
* After that, the checksum is added to the encryption payload over the full
|
||||
* message.
|
||||
* Crypter/signer can be omitted (by passing NULL) when no encryption
|
||||
* payload is expected.
|
||||
*
|
||||
* @param this message_t object
|
||||
* @param crypter crypter to use when a payload must be encrypted
|
||||
* @param signer signer to build a mac
|
||||
* @return
|
||||
* - SUCCESS if packet could be generated
|
||||
* - INVALID_STATE if exchange type is currently not set
|
||||
* - NOT_FOUND if no rules found for message generation
|
||||
* - INVALID_STATE if crypter/signer not supplied but needed.
|
||||
*/
|
||||
status_t (*generate) (message_t *this, crypter_t *crypter, signer_t *signer, packet_t **packet);
|
||||
|
||||
/**
|
||||
* @brief Gets the source host informations.
|
||||
*
|
||||
* @warning Returned host_t object is not getting cloned,
|
||||
* do not destroy nor modify.
|
||||
*
|
||||
* @param this message_t object
|
||||
* @return host_t object representing source host
|
||||
*/
|
||||
host_t * (*get_source) (message_t *this);
|
||||
|
||||
/**
|
||||
* @brief Sets the source host informations.
|
||||
*
|
||||
* @warning host_t object is not getting cloned and gets destroyed by
|
||||
* message_t.destroy or next call of message_t.set_source.
|
||||
*
|
||||
* @param this message_t object
|
||||
* @param host host_t object representing source host
|
||||
*/
|
||||
void (*set_source) (message_t *this, host_t *host);
|
||||
|
||||
/**
|
||||
* @brief Gets the destination host informations.
|
||||
*
|
||||
* @warning Returned host_t object is not getting cloned,
|
||||
* do not destroy nor modify.
|
||||
*
|
||||
* @param this message_t object
|
||||
* @return host_t object representing destination host
|
||||
*/
|
||||
host_t * (*get_destination) (message_t *this);
|
||||
|
||||
/**
|
||||
* @brief Sets the destination host informations.
|
||||
*
|
||||
* @warning host_t object is not getting cloned and gets destroyed by
|
||||
* message_t.destroy or next call of message_t.set_destination.
|
||||
*
|
||||
* @param this message_t object
|
||||
* @param host host_t object representing destination host
|
||||
*/
|
||||
void (*set_destination) (message_t *this, host_t *host);
|
||||
|
||||
/**
|
||||
* @brief Returns an iterator on all stored payloads.
|
||||
*
|
||||
* @warning Don't insert payloads over this iterator.
|
||||
* Use add_payload() instead.
|
||||
*
|
||||
* @param this message_t object
|
||||
* @return iterator_t object which has to get destroyd by the caller
|
||||
*/
|
||||
iterator_t * (*get_payload_iterator) (message_t *this);
|
||||
|
||||
/**
|
||||
* Returns a clone of the internal stored packet_t object.
|
||||
*
|
||||
* @param this message_t object
|
||||
* @return packet_t object as clone of internal one
|
||||
*/
|
||||
packet_t * (*get_packet) (message_t *this);
|
||||
|
||||
/**
|
||||
* Returns a clone of the internal stored packet_t data.
|
||||
*
|
||||
* @param this message_t object
|
||||
* @return clone of the internal stored packet_t data.
|
||||
*/
|
||||
chunk_t (*get_packet_data) (message_t *this);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Destroys a message and all including objects.
|
||||
*
|
||||
* @param this message_t object
|
||||
*/
|
||||
void (*destroy) (message_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Creates an message_t object from a incoming UDP Packet.
|
||||
*
|
||||
* @warning the given packet_t object is not copied and gets
|
||||
* destroyed in message_t's destroy call.
|
||||
*
|
||||
* @warning Packet is not parsed in here!
|
||||
*
|
||||
* - exchange_type is set to NOT_SET
|
||||
* - original_initiator is set to TRUE
|
||||
* - is_request is set to TRUE
|
||||
* Call message_t.parse_header afterwards.
|
||||
*
|
||||
* @param packet packet_t object which is assigned to message
|
||||
* @return message_t object
|
||||
*
|
||||
* @ingroup encoding
|
||||
*/
|
||||
message_t * message_create_from_packet(packet_t *packet);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Creates an empty message_t object.
|
||||
*
|
||||
* - exchange_type is set to NOT_SET
|
||||
* - original_initiator is set to TRUE
|
||||
* - is_request is set to TRUE
|
||||
*
|
||||
* @return message_t object
|
||||
*
|
||||
* @ingroup encoding
|
||||
*/
|
||||
message_t * message_create();
|
||||
|
||||
/**
|
||||
* @brief Creates an message_t object of type reply containing a notify payload.
|
||||
*
|
||||
* @return message_t object
|
||||
*
|
||||
* @ingroup encoding
|
||||
*/
|
||||
message_t *message_create_notify_reply(host_t *source, host_t *destination, exchange_type_t exchange_type, bool original_initiator,ike_sa_id_t *ike_sa_id,notify_message_type_t notify_type);
|
||||
|
||||
#endif /*MESSAGE_H_*/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* @file parser.h
|
||||
*
|
||||
* @brief Interface of parser_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef PARSER_H_
|
||||
#define PARSER_H_
|
||||
|
||||
#include <types.h>
|
||||
#include <encoding/payloads/encodings.h>
|
||||
#include <encoding/payloads/payload.h>
|
||||
|
||||
|
||||
typedef struct parser_t parser_t;
|
||||
|
||||
/**
|
||||
* @brief A parser_t class to parse IKEv2 payloads.
|
||||
*
|
||||
* A parser is used for parsing one chunk of data. Multiple
|
||||
* payloads can be parsed out of the chunk using parse_payload.
|
||||
* The parser remains the state until destroyed.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - parser_create()
|
||||
*
|
||||
* @ingroup encoding
|
||||
*/
|
||||
struct parser_t {
|
||||
|
||||
/**
|
||||
* @brief Parses the next payload.
|
||||
*
|
||||
* @warning Caller is responsible for freeing allocated payload.
|
||||
*
|
||||
* Rules for parsing are described in the payload definition.
|
||||
*
|
||||
* @param this parser_t bject
|
||||
* @param payload_type payload type to parse
|
||||
* @param[out] payload pointer where parsed payload was allocated
|
||||
* @return
|
||||
* - SUCCESSFUL if succeeded,
|
||||
* - PARSE_ERROR if corrupted/invalid data found
|
||||
*/
|
||||
status_t (*parse_payload) (parser_t *this, payload_type_t payload_type, payload_t **payload);
|
||||
|
||||
/**
|
||||
* Gets the remaining byte count which is not currently parsed.
|
||||
*
|
||||
* @param parser parser_t object
|
||||
*/
|
||||
int (*get_remaining_byte_count) (parser_t *this);
|
||||
|
||||
/**
|
||||
* @brief Resets the current parser context.
|
||||
*
|
||||
* @param parser parser_t object
|
||||
*/
|
||||
void (*reset_context) (parser_t *this);
|
||||
|
||||
/**
|
||||
* @brief Destroys a parser_t object.
|
||||
*
|
||||
* @param parser parser_t object
|
||||
*/
|
||||
void (*destroy) (parser_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Constructor to create a parser_t object.
|
||||
*
|
||||
* @param data chunk of data to parse with this parser_t object
|
||||
* @return parser_t object
|
||||
*
|
||||
* @ingroup encoding
|
||||
*/
|
||||
parser_t *parser_create(chunk_t data);
|
||||
|
||||
#endif /*PARSER_H_*/
|
||||
@@ -0,0 +1,108 @@
|
||||
# Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
# Hochschule fuer Technik Rapperswil
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the
|
||||
# Free Software Foundation; either version 2 of the License, or (at your
|
||||
# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# for more details.
|
||||
#
|
||||
|
||||
PAYLOADS_DIR= $(ENCODING_DIR)payloads/
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)encodings.o
|
||||
$(BUILD_DIR)encodings.o : $(PAYLOADS_DIR)encodings.c $(PAYLOADS_DIR)encodings.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)ike_header.o
|
||||
$(BUILD_DIR)ike_header.o : $(PAYLOADS_DIR)ike_header.c $(PAYLOADS_DIR)ike_header.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)ke_payload.o
|
||||
$(BUILD_DIR)ke_payload.o : $(PAYLOADS_DIR)ke_payload.c $(PAYLOADS_DIR)ke_payload.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)nonce_payload.o
|
||||
$(BUILD_DIR)nonce_payload.o : $(PAYLOADS_DIR)nonce_payload.c $(PAYLOADS_DIR)nonce_payload.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)notify_payload.o
|
||||
$(BUILD_DIR)notify_payload.o : $(PAYLOADS_DIR)notify_payload.c $(PAYLOADS_DIR)notify_payload.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)id_payload.o
|
||||
$(BUILD_DIR)id_payload.o : $(PAYLOADS_DIR)id_payload.c $(PAYLOADS_DIR)id_payload.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)auth_payload.o
|
||||
$(BUILD_DIR)auth_payload.o : $(PAYLOADS_DIR)auth_payload.c $(PAYLOADS_DIR)auth_payload.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)cert_payload.o
|
||||
$(BUILD_DIR)cert_payload.o : $(PAYLOADS_DIR)cert_payload.c $(PAYLOADS_DIR)cert_payload.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)certreq_payload.o
|
||||
$(BUILD_DIR)certreq_payload.o : $(PAYLOADS_DIR)certreq_payload.c $(PAYLOADS_DIR)certreq_payload.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)delete_payload.o
|
||||
$(BUILD_DIR)delete_payload.o : $(PAYLOADS_DIR)delete_payload.c $(PAYLOADS_DIR)delete_payload.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)vendor_id_payload.o
|
||||
$(BUILD_DIR)vendor_id_payload.o : $(PAYLOADS_DIR)vendor_id_payload.c $(PAYLOADS_DIR)vendor_id_payload.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)cp_payload.o
|
||||
$(BUILD_DIR)cp_payload.o : $(PAYLOADS_DIR)cp_payload.c $(PAYLOADS_DIR)cp_payload.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)configuration_attribute.o
|
||||
$(BUILD_DIR)configuration_attribute.o : $(PAYLOADS_DIR)configuration_attribute.c $(PAYLOADS_DIR)configuration_attribute.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)eap_payload.o
|
||||
$(BUILD_DIR)eap_payload.o : $(PAYLOADS_DIR)eap_payload.c $(PAYLOADS_DIR)eap_payload.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)unknown_payload.o
|
||||
$(BUILD_DIR)unknown_payload.o : $(PAYLOADS_DIR)unknown_payload.c $(PAYLOADS_DIR)unknown_payload.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)ts_payload.o
|
||||
$(BUILD_DIR)ts_payload.o : $(PAYLOADS_DIR)ts_payload.c $(PAYLOADS_DIR)ts_payload.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)traffic_selector_substructure.o
|
||||
$(BUILD_DIR)traffic_selector_substructure.o : $(PAYLOADS_DIR)traffic_selector_substructure.c $(PAYLOADS_DIR)traffic_selector_substructure.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)payload.o
|
||||
$(BUILD_DIR)payload.o : $(PAYLOADS_DIR)payload.c $(PAYLOADS_DIR)payload.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)proposal_substructure.o
|
||||
$(BUILD_DIR)proposal_substructure.o : $(PAYLOADS_DIR)proposal_substructure.c $(PAYLOADS_DIR)proposal_substructure.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)sa_payload.o
|
||||
$(BUILD_DIR)sa_payload.o : $(PAYLOADS_DIR)sa_payload.c $(PAYLOADS_DIR)sa_payload.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)transform_attribute.o
|
||||
$(BUILD_DIR)transform_attribute.o : $(PAYLOADS_DIR)transform_attribute.c $(PAYLOADS_DIR)transform_attribute.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)transform_substructure.o
|
||||
$(BUILD_DIR)transform_substructure.o : $(PAYLOADS_DIR)transform_substructure.c $(PAYLOADS_DIR)transform_substructure.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)encryption_payload.o
|
||||
$(BUILD_DIR)encryption_payload.o : $(PAYLOADS_DIR)encryption_payload.c $(PAYLOADS_DIR)encryption_payload.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
@@ -0,0 +1,265 @@
|
||||
/**
|
||||
* @file auth_payload.h
|
||||
*
|
||||
* @brief Implementation of auth_payload_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "auth_payload.h"
|
||||
|
||||
#include <encoding/payloads/encodings.h>
|
||||
|
||||
|
||||
typedef struct private_auth_payload_t private_auth_payload_t;
|
||||
|
||||
/**
|
||||
* Private data of an auth_payload_t object.
|
||||
*
|
||||
*/
|
||||
struct private_auth_payload_t {
|
||||
|
||||
/**
|
||||
* Public auth_payload_t interface.
|
||||
*/
|
||||
auth_payload_t public;
|
||||
|
||||
/**
|
||||
* Next payload type.
|
||||
*/
|
||||
u_int8_t next_payload;
|
||||
|
||||
/**
|
||||
* Critical flag.
|
||||
*/
|
||||
bool critical;
|
||||
|
||||
/**
|
||||
* Length of this payload.
|
||||
*/
|
||||
u_int16_t payload_length;
|
||||
|
||||
/**
|
||||
* Method of the AUTH Data.
|
||||
*/
|
||||
u_int8_t auth_method;
|
||||
|
||||
/**
|
||||
* The contained auth data value.
|
||||
*/
|
||||
chunk_t auth_data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Encoding rules to parse or generate a AUTH payload
|
||||
*
|
||||
* The defined offsets are the positions in a object of type
|
||||
* private_auth_payload_t.
|
||||
*
|
||||
*/
|
||||
encoding_rule_t auth_payload_encodings[] = {
|
||||
/* 1 Byte next payload type, stored in the field next_payload */
|
||||
{ U_INT_8, offsetof(private_auth_payload_t, next_payload) },
|
||||
/* the critical bit */
|
||||
{ FLAG, offsetof(private_auth_payload_t, critical) },
|
||||
/* 7 Bit reserved bits, nowhere stored */
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
/* Length of the whole payload*/
|
||||
{ PAYLOAD_LENGTH, offsetof(private_auth_payload_t, payload_length)},
|
||||
/* 1 Byte AUTH type*/
|
||||
{ U_INT_8, offsetof(private_auth_payload_t, auth_method) },
|
||||
/* 3 reserved bytes */
|
||||
{ RESERVED_BYTE, 0 },
|
||||
{ RESERVED_BYTE, 0 },
|
||||
{ RESERVED_BYTE, 0 },
|
||||
/* some auth data bytes, length is defined in PAYLOAD_LENGTH */
|
||||
{ AUTH_DATA, offsetof(private_auth_payload_t, auth_data) }
|
||||
};
|
||||
|
||||
/*
|
||||
1 2 3
|
||||
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 !C! RESERVED ! Payload Length !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! Auth Method ! RESERVED !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! !
|
||||
~ Authentication Data ~
|
||||
! !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.verify.
|
||||
*/
|
||||
static status_t verify(private_auth_payload_t *this)
|
||||
{
|
||||
if ((this->auth_method == 0) ||
|
||||
((this->auth_method >= 4) && (this->auth_method <= 200)))
|
||||
{
|
||||
/* reserved IDs */
|
||||
return FAILED;
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of auth_payload_t.get_encoding_rules.
|
||||
*/
|
||||
static void get_encoding_rules(private_auth_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
|
||||
{
|
||||
*rules = auth_payload_encodings;
|
||||
*rule_count = sizeof(auth_payload_encodings) / sizeof(encoding_rule_t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_type.
|
||||
*/
|
||||
static payload_type_t get_payload_type(private_auth_payload_t *this)
|
||||
{
|
||||
return AUTHENTICATION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_next_type.
|
||||
*/
|
||||
static payload_type_t get_next_type(private_auth_payload_t *this)
|
||||
{
|
||||
return (this->next_payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.set_next_type.
|
||||
*/
|
||||
static void set_next_type(private_auth_payload_t *this,payload_type_t type)
|
||||
{
|
||||
this->next_payload = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_length.
|
||||
*/
|
||||
static size_t get_length(private_auth_payload_t *this)
|
||||
{
|
||||
return this->payload_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of auth_payload_t.set_auth_method.
|
||||
*/
|
||||
static void set_auth_method (private_auth_payload_t *this, auth_method_t method)
|
||||
{
|
||||
this->auth_method = method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of auth_payload_t.get_auth_method.
|
||||
*/
|
||||
static auth_method_t get_auth_method (private_auth_payload_t *this)
|
||||
{
|
||||
return (this->auth_method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of auth_payload_t.set_data.
|
||||
*/
|
||||
static void set_data (private_auth_payload_t *this, chunk_t data)
|
||||
{
|
||||
if (this->auth_data.ptr != NULL)
|
||||
{
|
||||
chunk_free(&(this->auth_data));
|
||||
}
|
||||
this->auth_data.ptr = clalloc(data.ptr,data.len);
|
||||
this->auth_data.len = data.len;
|
||||
this->payload_length = AUTH_PAYLOAD_HEADER_LENGTH + this->auth_data.len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of auth_payload_t.get_data.
|
||||
*/
|
||||
static chunk_t get_data (private_auth_payload_t *this)
|
||||
{
|
||||
return (this->auth_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of auth_payload_t.get_data_clone.
|
||||
*/
|
||||
static chunk_t get_data_clone (private_auth_payload_t *this)
|
||||
{
|
||||
chunk_t cloned_data;
|
||||
if (this->auth_data.ptr == NULL)
|
||||
{
|
||||
return (this->auth_data);
|
||||
}
|
||||
cloned_data.ptr = clalloc(this->auth_data.ptr,this->auth_data.len);
|
||||
cloned_data.len = this->auth_data.len;
|
||||
return cloned_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.destroy and auth_payload_t.destroy.
|
||||
*/
|
||||
static void destroy(private_auth_payload_t *this)
|
||||
{
|
||||
if (this->auth_data.ptr != NULL)
|
||||
{
|
||||
chunk_free(&(this->auth_data));
|
||||
}
|
||||
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
auth_payload_t *auth_payload_create()
|
||||
{
|
||||
private_auth_payload_t *this = malloc_thing(private_auth_payload_t);
|
||||
|
||||
/* interface functions */
|
||||
this->public.payload_interface.verify = (status_t (*) (payload_t *))verify;
|
||||
this->public.payload_interface.get_encoding_rules = (void (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules;
|
||||
this->public.payload_interface.get_length = (size_t (*) (payload_t *)) get_length;
|
||||
this->public.payload_interface.get_next_type = (payload_type_t (*) (payload_t *)) get_next_type;
|
||||
this->public.payload_interface.set_next_type = (void (*) (payload_t *,payload_type_t)) set_next_type;
|
||||
this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_payload_type;
|
||||
this->public.payload_interface.destroy = (void (*) (payload_t *))destroy;
|
||||
|
||||
/* public functions */
|
||||
this->public.destroy = (void (*) (auth_payload_t *)) destroy;
|
||||
this->public.set_auth_method = (void (*) (auth_payload_t *,auth_method_t)) set_auth_method;
|
||||
this->public.get_auth_method = (auth_method_t (*) (auth_payload_t *)) get_auth_method;
|
||||
this->public.set_data = (void (*) (auth_payload_t *,chunk_t)) set_data;
|
||||
this->public.get_data_clone = (chunk_t (*) (auth_payload_t *)) get_data_clone;
|
||||
this->public.get_data = (chunk_t (*) (auth_payload_t *)) get_data;
|
||||
|
||||
/* private variables */
|
||||
this->critical = FALSE;
|
||||
this->next_payload = NO_PAYLOAD;
|
||||
this->payload_length =AUTH_PAYLOAD_HEADER_LENGTH;
|
||||
this->auth_data = CHUNK_INITIALIZER;
|
||||
|
||||
return (&(this->public));
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
/**
|
||||
* @file auth_payload.h
|
||||
*
|
||||
* @brief Interface of auth_payload_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef AUTH_PAYLOAD_H_
|
||||
#define AUTH_PAYLOAD_H_
|
||||
|
||||
#include <types.h>
|
||||
#include <encoding/payloads/payload.h>
|
||||
#include <config/connections/connection.h>
|
||||
|
||||
/**
|
||||
* Length of a auth payload without the auth data in bytes.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
#define AUTH_PAYLOAD_HEADER_LENGTH 8
|
||||
|
||||
|
||||
typedef struct auth_payload_t auth_payload_t;
|
||||
|
||||
/**
|
||||
* @brief Class representing an IKEv2 AUTH payload.
|
||||
*
|
||||
* The AUTH payload format is described in RFC section 3.8.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - auth_payload_create()
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
struct auth_payload_t {
|
||||
|
||||
/**
|
||||
* The payload_t interface.
|
||||
*/
|
||||
payload_t payload_interface;
|
||||
|
||||
/**
|
||||
* @brief Set the AUTH method.
|
||||
*
|
||||
* @param this calling auth_payload_t object
|
||||
* @param method auth_method_t to use
|
||||
*/
|
||||
void (*set_auth_method) (auth_payload_t *this, auth_method_t method);
|
||||
|
||||
/**
|
||||
* @brief Get the AUTH method.
|
||||
*
|
||||
* @param this calling auth_payload_t object
|
||||
* @return auth_method_t used
|
||||
*/
|
||||
auth_method_t (*get_auth_method) (auth_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Set the AUTH data.
|
||||
*
|
||||
* Data are getting cloned.
|
||||
*
|
||||
* @param this calling auth_payload_t object
|
||||
* @param data AUTH data as chunk_t
|
||||
*/
|
||||
void (*set_data) (auth_payload_t *this, chunk_t data);
|
||||
|
||||
/**
|
||||
* @brief Get the AUTH data.
|
||||
*
|
||||
* Returned data are a copy of the internal one.
|
||||
*
|
||||
* @param this calling auth_payload_t object
|
||||
* @return AUTH data as chunk_t
|
||||
*/
|
||||
chunk_t (*get_data_clone) (auth_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get the AUTH data.
|
||||
*
|
||||
* Returned data are NOT copied
|
||||
*
|
||||
* @param this calling auth_payload_t object
|
||||
* @return AUTH data as chunk_t
|
||||
*/
|
||||
chunk_t (*get_data) (auth_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Destroys an auth_payload_t object.
|
||||
*
|
||||
* @param this auth_payload_t object to destroy
|
||||
*/
|
||||
void (*destroy) (auth_payload_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Creates an empty auth_payload_t object.
|
||||
*
|
||||
* @return auth_payload_t object
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
auth_payload_t *auth_payload_create();
|
||||
|
||||
|
||||
#endif /* AUTH_PAYLOAD_H_ */
|
||||
@@ -0,0 +1,279 @@
|
||||
/**
|
||||
* @file cert_payload.c
|
||||
*
|
||||
* @brief Implementation of cert_payload_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "cert_payload.h"
|
||||
|
||||
|
||||
/**
|
||||
* String mappings for cert_encoding_t.
|
||||
*/
|
||||
mapping_t cert_encoding_m[] = {
|
||||
{PKCS7_WRAPPED_X509_CERTIFICATE, "PKCS7_WRAPPED_X509_CERTIFICATE"},
|
||||
{PGP_CERTIFICATE, "PGP_CERTIFICATE"},
|
||||
{DNS_SIGNED_KEY, "DNS_SIGNED_KEY"},
|
||||
{X509_CERTIFICATE_SIGNATURE, "X509_CERTIFICATE_SIGNATURE"},
|
||||
{KERBEROS_TOKEN, "KERBEROS_TOKEN"},
|
||||
{CERTIFICATE_REVOCATION_LIST, "CERTIFICATE_REVOCATION_LIST"},
|
||||
{AUTHORITY_REVOCATION_LIST, "AUTHORITY_REVOCATION_LIST"},
|
||||
{SPKI_CERTIFICATE, "SPKI_CERTIFICATE"},
|
||||
{X509_CERTIFICATE_ATTRIBUTE, "X509_CERTIFICATE_ATTRIBUTE"},
|
||||
{RAW_SA_KEY, "RAW_SA_KEY"},
|
||||
{HASH_AND_URL_X509_CERTIFICATE, "HASH_AND_URL_X509_CERTIFICATE"},
|
||||
{HASH_AND_URL_X509_BUNDLE, "HASH_AND_URL_X509_BUNDLE"},
|
||||
{MAPPING_END, NULL}
|
||||
};
|
||||
|
||||
|
||||
typedef struct private_cert_payload_t private_cert_payload_t;
|
||||
|
||||
/**
|
||||
* Private data of an cert_payload_t object.
|
||||
*
|
||||
*/
|
||||
struct private_cert_payload_t {
|
||||
/**
|
||||
* Public cert_payload_t interface.
|
||||
*/
|
||||
cert_payload_t public;
|
||||
|
||||
/**
|
||||
* Next payload type.
|
||||
*/
|
||||
u_int8_t next_payload;
|
||||
|
||||
/**
|
||||
* Critical flag.
|
||||
*/
|
||||
bool critical;
|
||||
|
||||
/**
|
||||
* Length of this payload.
|
||||
*/
|
||||
u_int16_t payload_length;
|
||||
|
||||
/**
|
||||
* Encoding of the CERT Data.
|
||||
*/
|
||||
u_int8_t cert_encoding;
|
||||
|
||||
/**
|
||||
* The contained cert data value.
|
||||
*/
|
||||
chunk_t cert_data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Encoding rules to parse or generate a CERT payload
|
||||
*
|
||||
* The defined offsets are the positions in a object of type
|
||||
* private_cert_payload_t.
|
||||
*
|
||||
*/
|
||||
encoding_rule_t cert_payload_encodings[] = {
|
||||
/* 1 Byte next payload type, stored in the field next_payload */
|
||||
{ U_INT_8, offsetof(private_cert_payload_t, next_payload) },
|
||||
/* the critical bit */
|
||||
{ FLAG, offsetof(private_cert_payload_t, critical) },
|
||||
/* 7 Bit reserved bits, nowhere stored */
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
/* Length of the whole payload*/
|
||||
{ PAYLOAD_LENGTH, offsetof(private_cert_payload_t, payload_length)},
|
||||
/* 1 Byte CERT type*/
|
||||
{ U_INT_8, offsetof(private_cert_payload_t, cert_encoding) },
|
||||
/* some cert data bytes, length is defined in PAYLOAD_LENGTH */
|
||||
{ CERT_DATA, offsetof(private_cert_payload_t, cert_data) }
|
||||
};
|
||||
|
||||
/*
|
||||
1 2 3
|
||||
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 !C! RESERVED ! Payload Length !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! Cert Encoding ! !
|
||||
+-+-+-+-+-+-+-+-+ !
|
||||
~ Certificate Data ~
|
||||
! !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.verify.
|
||||
*/
|
||||
static status_t verify(private_cert_payload_t *this)
|
||||
{
|
||||
if ((this->cert_encoding == 0) ||
|
||||
((this->cert_encoding >= 14) && (this->cert_encoding <= 200)))
|
||||
{
|
||||
/* reserved IDs */
|
||||
return FAILED;
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of cert_payload_t.get_encoding_rules.
|
||||
*/
|
||||
static void get_encoding_rules(private_cert_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
|
||||
{
|
||||
*rules = cert_payload_encodings;
|
||||
*rule_count = sizeof(cert_payload_encodings) / sizeof(encoding_rule_t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_type.
|
||||
*/
|
||||
static payload_type_t get_payload_type(private_cert_payload_t *this)
|
||||
{
|
||||
return CERTIFICATE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_next_type.
|
||||
*/
|
||||
static payload_type_t get_next_type(private_cert_payload_t *this)
|
||||
{
|
||||
return (this->next_payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.set_next_type.
|
||||
*/
|
||||
static void set_next_type(private_cert_payload_t *this,payload_type_t type)
|
||||
{
|
||||
this->next_payload = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_length.
|
||||
*/
|
||||
static size_t get_length(private_cert_payload_t *this)
|
||||
{
|
||||
return this->payload_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of cert_payload_t.set_cert_encoding.
|
||||
*/
|
||||
static void set_cert_encoding (private_cert_payload_t *this, cert_encoding_t encoding)
|
||||
{
|
||||
this->cert_encoding = encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of cert_payload_t.get_cert_encoding.
|
||||
*/
|
||||
static cert_encoding_t get_cert_encoding (private_cert_payload_t *this)
|
||||
{
|
||||
return (this->cert_encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of cert_payload_t.set_data.
|
||||
*/
|
||||
static void set_data (private_cert_payload_t *this, chunk_t data)
|
||||
{
|
||||
if (this->cert_data.ptr != NULL)
|
||||
{
|
||||
chunk_free(&(this->cert_data));
|
||||
}
|
||||
this->cert_data.ptr = clalloc(data.ptr,data.len);
|
||||
this->cert_data.len = data.len;
|
||||
this->payload_length = CERT_PAYLOAD_HEADER_LENGTH + this->cert_data.len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of cert_payload_t.get_data.
|
||||
*/
|
||||
static chunk_t get_data (private_cert_payload_t *this)
|
||||
{
|
||||
return (this->cert_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of cert_payload_t.get_data_clone.
|
||||
*/
|
||||
static chunk_t get_data_clone (private_cert_payload_t *this)
|
||||
{
|
||||
chunk_t cloned_data;
|
||||
if (this->cert_data.ptr == NULL)
|
||||
{
|
||||
return (this->cert_data);
|
||||
}
|
||||
cloned_data.ptr = clalloc(this->cert_data.ptr,this->cert_data.len);
|
||||
cloned_data.len = this->cert_data.len;
|
||||
return cloned_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.destroy and cert_payload_t.destroy.
|
||||
*/
|
||||
static void destroy(private_cert_payload_t *this)
|
||||
{
|
||||
if (this->cert_data.ptr != NULL)
|
||||
{
|
||||
chunk_free(&(this->cert_data));
|
||||
}
|
||||
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
cert_payload_t *cert_payload_create()
|
||||
{
|
||||
private_cert_payload_t *this = malloc_thing(private_cert_payload_t);
|
||||
|
||||
/* interface functions */
|
||||
this->public.payload_interface.verify = (status_t (*) (payload_t *))verify;
|
||||
this->public.payload_interface.get_encoding_rules = (void (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules;
|
||||
this->public.payload_interface.get_length = (size_t (*) (payload_t *)) get_length;
|
||||
this->public.payload_interface.get_next_type = (payload_type_t (*) (payload_t *)) get_next_type;
|
||||
this->public.payload_interface.set_next_type = (void (*) (payload_t *,payload_type_t)) set_next_type;
|
||||
this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_payload_type;
|
||||
this->public.payload_interface.destroy = (void (*) (payload_t *))destroy;
|
||||
|
||||
/* public functions */
|
||||
this->public.destroy = (void (*) (cert_payload_t *)) destroy;
|
||||
this->public.set_cert_encoding = (void (*) (cert_payload_t *,cert_encoding_t)) set_cert_encoding;
|
||||
this->public.get_cert_encoding = (cert_encoding_t (*) (cert_payload_t *)) get_cert_encoding;
|
||||
this->public.set_data = (void (*) (cert_payload_t *,chunk_t)) set_data;
|
||||
this->public.get_data_clone = (chunk_t (*) (cert_payload_t *)) get_data_clone;
|
||||
this->public.get_data = (chunk_t (*) (cert_payload_t *)) get_data;
|
||||
|
||||
/* private variables */
|
||||
this->critical = FALSE;
|
||||
this->next_payload = NO_PAYLOAD;
|
||||
this->payload_length =CERT_PAYLOAD_HEADER_LENGTH;
|
||||
this->cert_data = CHUNK_INITIALIZER;
|
||||
|
||||
return (&(this->public));
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
/**
|
||||
* @file cert_payload.h
|
||||
*
|
||||
* @brief Interface of cert_payload_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef CERT_PAYLOAD_H_
|
||||
#define CERT_PAYLOAD_H_
|
||||
|
||||
#include <types.h>
|
||||
#include <encoding/payloads/payload.h>
|
||||
|
||||
/**
|
||||
* Length of a cert payload without the cert data in bytes.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
#define CERT_PAYLOAD_HEADER_LENGTH 5
|
||||
|
||||
|
||||
typedef enum cert_encoding_t cert_encoding_t;
|
||||
|
||||
/**
|
||||
* @brief Certificate encoding, as described in IKEv2 RFC section 3.6
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
enum cert_encoding_t {
|
||||
PKCS7_WRAPPED_X509_CERTIFICATE = 1,
|
||||
PGP_CERTIFICATE = 2,
|
||||
DNS_SIGNED_KEY = 3,
|
||||
X509_CERTIFICATE_SIGNATURE = 4,
|
||||
KERBEROS_TOKEN = 6,
|
||||
CERTIFICATE_REVOCATION_LIST = 7,
|
||||
AUTHORITY_REVOCATION_LIST = 8,
|
||||
SPKI_CERTIFICATE = 9,
|
||||
X509_CERTIFICATE_ATTRIBUTE = 10,
|
||||
RAW_SA_KEY = 11,
|
||||
HASH_AND_URL_X509_CERTIFICATE = 12,
|
||||
HASH_AND_URL_X509_BUNDLE = 13
|
||||
};
|
||||
|
||||
/**
|
||||
* string mappings for cert_encoding_t.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
extern mapping_t cert_encoding_m[];
|
||||
|
||||
|
||||
typedef struct cert_payload_t cert_payload_t;
|
||||
|
||||
/**
|
||||
* @brief Class representing an IKEv2 CERT payload.
|
||||
*
|
||||
* The CERT payload format is described in RFC section 3.6.
|
||||
* This is just a dummy implementation to fullfill the standards
|
||||
* requirements. A full implementation would offer setters/getters
|
||||
* for the different encoding types.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - cert_payload_create()
|
||||
*
|
||||
* @todo Implement setters/getters for the different certificate encodings.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
struct cert_payload_t {
|
||||
|
||||
/**
|
||||
* The payload_t interface.
|
||||
*/
|
||||
payload_t payload_interface;
|
||||
|
||||
/**
|
||||
* @brief Set the CERT encoding.
|
||||
*
|
||||
* @param this calling cert_payload_t object
|
||||
* @param encoding CERT encoding
|
||||
*/
|
||||
void (*set_cert_encoding) (cert_payload_t *this, cert_encoding_t encoding);
|
||||
|
||||
/**
|
||||
* @brief Get the CERT encoding.
|
||||
*
|
||||
* @param this calling cert_payload_t object
|
||||
* @return Encoding of the CERT
|
||||
*/
|
||||
cert_encoding_t (*get_cert_encoding) (cert_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Set the CERT data.
|
||||
*
|
||||
* Data are getting cloned.
|
||||
*
|
||||
* @param this calling cert_payload_t object
|
||||
* @param data CERT data as chunk_t
|
||||
*/
|
||||
void (*set_data) (cert_payload_t *this, chunk_t data);
|
||||
|
||||
/**
|
||||
* @brief Get the CERT data.
|
||||
*
|
||||
* Returned data are a copy of the internal one.
|
||||
*
|
||||
* @param this calling cert_payload_t object
|
||||
* @return CERT data as chunk_t
|
||||
*/
|
||||
chunk_t (*get_data_clone) (cert_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get the CERT data.
|
||||
*
|
||||
* Returned data are NOT copied.
|
||||
*
|
||||
* @param this calling cert_payload_t object
|
||||
* @return CERT data as chunk_t
|
||||
*/
|
||||
chunk_t (*get_data) (cert_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Destroys an cert_payload_t object.
|
||||
*
|
||||
* @param this cert_payload_t object to destroy
|
||||
*/
|
||||
void (*destroy) (cert_payload_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Creates an empty cert_payload_t object.
|
||||
*
|
||||
* @return cert_payload_t object
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
cert_payload_t *cert_payload_create();
|
||||
|
||||
|
||||
#endif /* CERT_PAYLOAD_H_ */
|
||||
@@ -0,0 +1,259 @@
|
||||
/**
|
||||
* @file certreq_payload.c
|
||||
*
|
||||
* @brief Implementation of certreq_payload_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "certreq_payload.h"
|
||||
|
||||
|
||||
typedef struct private_certreq_payload_t private_certreq_payload_t;
|
||||
|
||||
/**
|
||||
* Private data of an certreq_payload_t object.
|
||||
*
|
||||
*/
|
||||
struct private_certreq_payload_t {
|
||||
/**
|
||||
* Public certreq_payload_t interface.
|
||||
*/
|
||||
certreq_payload_t public;
|
||||
|
||||
/**
|
||||
* Next payload type.
|
||||
*/
|
||||
u_int8_t next_payload;
|
||||
|
||||
/**
|
||||
* Critical flag.
|
||||
*/
|
||||
bool critical;
|
||||
|
||||
/**
|
||||
* Length of this payload.
|
||||
*/
|
||||
u_int16_t payload_length;
|
||||
|
||||
/**
|
||||
* Encoding of the CERT Data.
|
||||
*/
|
||||
u_int8_t cert_encoding;
|
||||
|
||||
/**
|
||||
* The contained certreq data value.
|
||||
*/
|
||||
chunk_t certreq_data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Encoding rules to parse or generate a CERTREQ payload
|
||||
*
|
||||
* The defined offsets are the positions in a object of type
|
||||
* private_certreq_payload_t.
|
||||
*
|
||||
*/
|
||||
encoding_rule_t certreq_payload_encodings[] = {
|
||||
/* 1 Byte next payload type, stored in the field next_payload */
|
||||
{ U_INT_8, offsetof(private_certreq_payload_t, next_payload) },
|
||||
/* the critical bit */
|
||||
{ FLAG, offsetof(private_certreq_payload_t, critical) },
|
||||
/* 7 Bit reserved bits, nowhere stored */
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
/* Length of the whole payload*/
|
||||
{ PAYLOAD_LENGTH, offsetof(private_certreq_payload_t, payload_length)},
|
||||
/* 1 Byte CERTREQ type*/
|
||||
{ U_INT_8, offsetof(private_certreq_payload_t, cert_encoding)},
|
||||
/* some certreq data bytes, length is defined in PAYLOAD_LENGTH */
|
||||
{ CERTREQ_DATA, offsetof(private_certreq_payload_t, certreq_data)}
|
||||
};
|
||||
|
||||
/*
|
||||
1 2 3
|
||||
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 !C! RESERVED ! Payload Length !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! Cert Encoding ! !
|
||||
+-+-+-+-+-+-+-+-+ !
|
||||
~ Certification Authority ~
|
||||
! !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.verify.
|
||||
*/
|
||||
static status_t verify(private_certreq_payload_t *this)
|
||||
{
|
||||
if ((this->cert_encoding == 0) ||
|
||||
((this->cert_encoding >= 14) && (this->cert_encoding <= 200)))
|
||||
{
|
||||
/* reserved IDs */
|
||||
return FAILED;
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of certreq_payload_t.get_encoding_rules.
|
||||
*/
|
||||
static void get_encoding_rules(private_certreq_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
|
||||
{
|
||||
*rules = certreq_payload_encodings;
|
||||
*rule_count = sizeof(certreq_payload_encodings) / sizeof(encoding_rule_t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_type.
|
||||
*/
|
||||
static payload_type_t get_payload_type(private_certreq_payload_t *this)
|
||||
{
|
||||
return CERTIFICATE_REQUEST;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_next_type.
|
||||
*/
|
||||
static payload_type_t get_next_type(private_certreq_payload_t *this)
|
||||
{
|
||||
return (this->next_payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.set_next_type.
|
||||
*/
|
||||
static void set_next_type(private_certreq_payload_t *this,payload_type_t type)
|
||||
{
|
||||
this->next_payload = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_length.
|
||||
*/
|
||||
static size_t get_length(private_certreq_payload_t *this)
|
||||
{
|
||||
return this->payload_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of certreq_payload_t.set_cert_encoding.
|
||||
*/
|
||||
static void set_cert_encoding (private_certreq_payload_t *this, cert_encoding_t encoding)
|
||||
{
|
||||
this->cert_encoding = encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of certreq_payload_t.get_cert_encoding.
|
||||
*/
|
||||
static cert_encoding_t get_cert_encoding (private_certreq_payload_t *this)
|
||||
{
|
||||
return (this->cert_encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of certreq_payload_t.set_data.
|
||||
*/
|
||||
static void set_data (private_certreq_payload_t *this, chunk_t data)
|
||||
{
|
||||
if (this->certreq_data.ptr != NULL)
|
||||
{
|
||||
chunk_free(&(this->certreq_data));
|
||||
}
|
||||
this->certreq_data.ptr = clalloc(data.ptr,data.len);
|
||||
this->certreq_data.len = data.len;
|
||||
this->payload_length = CERTREQ_PAYLOAD_HEADER_LENGTH + this->certreq_data.len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of certreq_payload_t.get_data.
|
||||
*/
|
||||
static chunk_t get_data (private_certreq_payload_t *this)
|
||||
{
|
||||
return (this->certreq_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of certreq_payload_t.get_data_clone.
|
||||
*/
|
||||
static chunk_t get_data_clone (private_certreq_payload_t *this)
|
||||
{
|
||||
chunk_t cloned_data;
|
||||
if (this->certreq_data.ptr == NULL)
|
||||
{
|
||||
return (this->certreq_data);
|
||||
}
|
||||
cloned_data.ptr = clalloc(this->certreq_data.ptr,this->certreq_data.len);
|
||||
cloned_data.len = this->certreq_data.len;
|
||||
return cloned_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.destroy and certreq_payload_t.destroy.
|
||||
*/
|
||||
static void destroy(private_certreq_payload_t *this)
|
||||
{
|
||||
if (this->certreq_data.ptr != NULL)
|
||||
{
|
||||
chunk_free(&(this->certreq_data));
|
||||
}
|
||||
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
certreq_payload_t *certreq_payload_create()
|
||||
{
|
||||
private_certreq_payload_t *this = malloc_thing(private_certreq_payload_t);
|
||||
|
||||
/* interface functions */
|
||||
this->public.payload_interface.verify = (status_t (*) (payload_t *))verify;
|
||||
this->public.payload_interface.get_encoding_rules = (void (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules;
|
||||
this->public.payload_interface.get_length = (size_t (*) (payload_t *)) get_length;
|
||||
this->public.payload_interface.get_next_type = (payload_type_t (*) (payload_t *)) get_next_type;
|
||||
this->public.payload_interface.set_next_type = (void (*) (payload_t *,payload_type_t)) set_next_type;
|
||||
this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_payload_type;
|
||||
this->public.payload_interface.destroy = (void (*) (payload_t *))destroy;
|
||||
|
||||
/* public functions */
|
||||
this->public.destroy = (void (*) (certreq_payload_t *)) destroy;
|
||||
this->public.set_cert_encoding = (void (*) (certreq_payload_t *,cert_encoding_t)) set_cert_encoding;
|
||||
this->public.get_cert_encoding = (cert_encoding_t (*) (certreq_payload_t *)) get_cert_encoding;
|
||||
this->public.set_data = (void (*) (certreq_payload_t *,chunk_t)) set_data;
|
||||
this->public.get_data_clone = (chunk_t (*) (certreq_payload_t *)) get_data_clone;
|
||||
this->public.get_data = (chunk_t (*) (certreq_payload_t *)) get_data;
|
||||
|
||||
/* private variables */
|
||||
this->critical = FALSE;
|
||||
this->next_payload = NO_PAYLOAD;
|
||||
this->payload_length =CERTREQ_PAYLOAD_HEADER_LENGTH;
|
||||
this->certreq_data = CHUNK_INITIALIZER;
|
||||
|
||||
return (&(this->public));
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
/**
|
||||
* @file certreq_payload.h
|
||||
*
|
||||
* @brief Interface of certreq_payload_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef CERTREQ_PAYLOAD_H_
|
||||
#define CERTREQ_PAYLOAD_H_
|
||||
|
||||
#include <types.h>
|
||||
#include <encoding/payloads/payload.h>
|
||||
#include <encoding/payloads/cert_payload.h>
|
||||
|
||||
/**
|
||||
* Length of a CERTREQ payload without the CERTREQ data in bytes.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
#define CERTREQ_PAYLOAD_HEADER_LENGTH 5
|
||||
|
||||
|
||||
typedef struct certreq_payload_t certreq_payload_t;
|
||||
|
||||
/**
|
||||
* @brief Class representing an IKEv2 CERTREQ payload.
|
||||
*
|
||||
* The CERTREQ payload format is described in RFC section 3.7.
|
||||
* This is just a dummy implementation to fullfill the standards
|
||||
* requirements. A full implementation would offer setters/getters
|
||||
* for the different encoding types.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - certreq_payload_create()
|
||||
*
|
||||
* @todo Implement payload functionality.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
struct certreq_payload_t {
|
||||
/**
|
||||
* The payload_t interface.
|
||||
*/
|
||||
payload_t payload_interface;
|
||||
|
||||
/**
|
||||
* @brief Set the CERT encoding.
|
||||
*
|
||||
* @param this calling certreq_payload_t object
|
||||
* @param encoding CERT encoding
|
||||
*/
|
||||
void (*set_cert_encoding) (certreq_payload_t *this, cert_encoding_t encoding);
|
||||
|
||||
/**
|
||||
* @brief Get the CERT encoding.
|
||||
*
|
||||
* @param this calling certreq_payload_t object
|
||||
* @return Encoding of the CERT
|
||||
*/
|
||||
cert_encoding_t (*get_cert_encoding) (certreq_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Set the CERTREQ data.
|
||||
*
|
||||
* Data are getting cloned.
|
||||
*
|
||||
* @param this calling certreq_payload_t object
|
||||
* @param data CERTREQ data as chunk_t
|
||||
*/
|
||||
void (*set_data) (certreq_payload_t *this, chunk_t data);
|
||||
|
||||
/**
|
||||
* @brief Get the CERTREQ data.
|
||||
*
|
||||
* Returned data are a copy of the internal one.
|
||||
*
|
||||
* @param this calling certreq_payload_t object
|
||||
* @return CERTREQ data as chunk_t
|
||||
*/
|
||||
chunk_t (*get_data_clone) (certreq_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get the CERTREQ data.
|
||||
*
|
||||
* Returned data are NOT copied.
|
||||
*
|
||||
* @param this calling certreq_payload_t object
|
||||
* @return CERTREQ data as chunk_t
|
||||
*/
|
||||
chunk_t (*get_data) (certreq_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Destroys an certreq_payload_t object.
|
||||
*
|
||||
* @param this certreq_payload_t object to destroy
|
||||
*/
|
||||
void (*destroy) (certreq_payload_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Creates an empty certreq_payload_t object.
|
||||
*
|
||||
* @return certreq_payload_t object
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
certreq_payload_t *certreq_payload_create();
|
||||
|
||||
|
||||
#endif /* CERTREQ_PAYLOAD_H_ */
|
||||
@@ -0,0 +1,282 @@
|
||||
/**
|
||||
* @file configuration_attribute.c
|
||||
*
|
||||
* @brief Implementation of configuration_attribute_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "configuration_attribute.h"
|
||||
|
||||
#include <encoding/payloads/encodings.h>
|
||||
#include <types.h>
|
||||
|
||||
|
||||
typedef struct private_configuration_attribute_t private_configuration_attribute_t;
|
||||
|
||||
/**
|
||||
* Private data of an configuration_attribute_t object.
|
||||
*
|
||||
*/
|
||||
struct private_configuration_attribute_t {
|
||||
/**
|
||||
* Public configuration_attribute_t interface.
|
||||
*/
|
||||
configuration_attribute_t public;
|
||||
|
||||
/**
|
||||
* Type of the attribute.
|
||||
*/
|
||||
u_int16_t attribute_type;
|
||||
|
||||
/**
|
||||
* Length of the attribute.
|
||||
*/
|
||||
u_int16_t attribute_length;
|
||||
|
||||
|
||||
/**
|
||||
* Attribute value as chunk.
|
||||
*/
|
||||
chunk_t attribute_value;
|
||||
};
|
||||
|
||||
/**
|
||||
* String mappings for configuration_attribute_type_t.
|
||||
*/
|
||||
mapping_t configuration_attribute_type_m[] = {
|
||||
{INTERNAL_IP4_ADDRESS, "INTERNAL_IP4_ADDRESS"},
|
||||
{INTERNAL_IP4_NETMASK, "INTERNAL_IP4_NETMASK"},
|
||||
{INTERNAL_IP4_DNS, "INTERNAL_IP4_DNS"},
|
||||
{INTERNAL_IP4_NBNS, "INTERNAL_IP4_NBNS"},
|
||||
{INTERNAL_ADDRESS_EXPIRY, "INTERNAL_ADDRESS_EXPIRY"},
|
||||
{INTERNAL_IP4_DHCP, "INTERNAL_IP4_DHCP"},
|
||||
{APPLICATION_VERSION, "APPLICATION_VERSION"},
|
||||
{INTERNAL_IP6_ADDRESS, "INTERNAL_IP6_ADDRESS"},
|
||||
{INTERNAL_IP6_DNS, "INTERNAL_IP6_DNS"},
|
||||
{INTERNAL_IP6_NBNS, "INTERNAL_IP6_NBNS"},
|
||||
{INTERNAL_IP6_DHCP, "INTERNAL_IP6_DHCP"},
|
||||
{INTERNAL_IP4_SUBNET, "INTERNAL_IP4_SUBNET"},
|
||||
{SUPPORTED_ATTRIBUTES, "SUPPORTED_ATTRIBUTES"},
|
||||
{INTERNAL_IP6_SUBNET, "INTERNAL_IP6_SUBNET"},
|
||||
{MAPPING_END, NULL}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Encoding rules to parse or generate a configuration attribute.
|
||||
*
|
||||
* The defined offsets are the positions in a object of type
|
||||
* private_configuration_attribute_t.
|
||||
*
|
||||
*/
|
||||
encoding_rule_t configuration_attribute_encodings[] = {
|
||||
|
||||
{ RESERVED_BIT, 0 },
|
||||
/* type of the attribute as 15 bit unsigned integer */
|
||||
{ ATTRIBUTE_TYPE, offsetof(private_configuration_attribute_t, attribute_type) },
|
||||
/* Length of attribute value */
|
||||
{ CONFIGURATION_ATTRIBUTE_LENGTH, offsetof(private_configuration_attribute_t, attribute_length)},
|
||||
/* Value of attribute if attribute format flag is zero */
|
||||
{ CONFIGURATION_ATTRIBUTE_VALUE, offsetof(private_configuration_attribute_t, attribute_value)}
|
||||
};
|
||||
|
||||
/*
|
||||
1 2 3
|
||||
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
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
!R| Attribute Type ! Length |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| |
|
||||
~ Value ~
|
||||
| |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.verify.
|
||||
*/
|
||||
static status_t verify(private_configuration_attribute_t *this)
|
||||
{
|
||||
switch (this->attribute_type)
|
||||
{
|
||||
case INTERNAL_IP4_ADDRESS:
|
||||
case INTERNAL_IP4_NETMASK:
|
||||
case INTERNAL_IP4_DNS:
|
||||
case INTERNAL_IP4_NBNS:
|
||||
case INTERNAL_ADDRESS_EXPIRY:
|
||||
case INTERNAL_IP4_DHCP:
|
||||
case APPLICATION_VERSION:
|
||||
case INTERNAL_IP6_ADDRESS:
|
||||
case INTERNAL_IP6_DNS:
|
||||
case INTERNAL_IP6_NBNS:
|
||||
case INTERNAL_IP6_DHCP:
|
||||
case INTERNAL_IP4_SUBNET:
|
||||
case SUPPORTED_ATTRIBUTES:
|
||||
case INTERNAL_IP6_SUBNET:
|
||||
{
|
||||
/* Attribute types are not checked in here */
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
if (this->attribute_length != this->attribute_value.len)
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_encoding_rules.
|
||||
*/
|
||||
static void get_encoding_rules(private_configuration_attribute_t *this, encoding_rule_t **rules, size_t *rule_count)
|
||||
{
|
||||
*rules = configuration_attribute_encodings;
|
||||
*rule_count = sizeof(configuration_attribute_encodings) / sizeof(encoding_rule_t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_type.
|
||||
*/
|
||||
static payload_type_t get_type(private_configuration_attribute_t *this)
|
||||
{
|
||||
return CONFIGURATION_ATTRIBUTE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_next_type.
|
||||
*/
|
||||
static payload_type_t get_next_type(private_configuration_attribute_t *this)
|
||||
{
|
||||
return (NO_PAYLOAD);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.set_next_type.
|
||||
*/
|
||||
static void set_next_type(private_configuration_attribute_t *this,payload_type_t type)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of configuration_attribute_t.get_length.
|
||||
*/
|
||||
static size_t get_length(private_configuration_attribute_t *this)
|
||||
{
|
||||
return (this->attribute_value.len + CONFIGURATION_ATTRIBUTE_HEADER_LENGTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of configuration_attribute_t.set_value.
|
||||
*/
|
||||
static void set_value(private_configuration_attribute_t *this, chunk_t value)
|
||||
{
|
||||
if (this->attribute_value.ptr != NULL)
|
||||
{
|
||||
/* free existing value */
|
||||
chunk_free(&(this->attribute_value));
|
||||
}
|
||||
|
||||
this->attribute_value.ptr = clalloc(value.ptr,value.len);
|
||||
this->attribute_value.len = value.len;
|
||||
|
||||
this->attribute_length = this->attribute_value.len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of configuration_attribute_t.get_value.
|
||||
*/
|
||||
static chunk_t get_value (private_configuration_attribute_t *this)
|
||||
{
|
||||
return this->attribute_value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of configuration_attribute_t.set_attribute_type.
|
||||
*/
|
||||
static void set_attribute_type (private_configuration_attribute_t *this, u_int16_t type)
|
||||
{
|
||||
this->attribute_type = type & 0x7FFF;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of configuration_attribute_t.get_attribute_type.
|
||||
*/
|
||||
static u_int16_t get_attribute_type (private_configuration_attribute_t *this)
|
||||
{
|
||||
return this->attribute_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of configuration_attribute_t.get_attribute_length.
|
||||
*/
|
||||
static u_int16_t get_attribute_length (private_configuration_attribute_t *this)
|
||||
{
|
||||
return this->attribute_length;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of configuration_attribute_t.destroy and payload_t.destroy.
|
||||
*/
|
||||
static void destroy(private_configuration_attribute_t *this)
|
||||
{
|
||||
if (this->attribute_value.ptr != NULL)
|
||||
{
|
||||
free(this->attribute_value.ptr);
|
||||
}
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
configuration_attribute_t *configuration_attribute_create()
|
||||
{
|
||||
private_configuration_attribute_t *this = malloc_thing(private_configuration_attribute_t);
|
||||
|
||||
/* payload interface */
|
||||
this->public.payload_interface.verify = (status_t (*) (payload_t *))verify;
|
||||
this->public.payload_interface.get_encoding_rules = (void (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules;
|
||||
this->public.payload_interface.get_length = (size_t (*) (payload_t *)) get_length;
|
||||
this->public.payload_interface.get_next_type = (payload_type_t (*) (payload_t *)) get_next_type;
|
||||
this->public.payload_interface.set_next_type = (void (*) (payload_t *,payload_type_t)) set_next_type;
|
||||
this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_type;
|
||||
this->public.payload_interface.destroy = (void (*) (payload_t *))destroy;
|
||||
|
||||
/* public functions */
|
||||
this->public.set_value = (void (*) (configuration_attribute_t *,chunk_t)) set_value;
|
||||
this->public.get_value = (chunk_t (*) (configuration_attribute_t *)) get_value;
|
||||
this->public.set_attribute_type = (void (*) (configuration_attribute_t *,u_int16_t type)) set_attribute_type;
|
||||
this->public.get_attribute_type = (u_int16_t (*) (configuration_attribute_t *)) get_attribute_type;
|
||||
this->public.get_attribute_length = (u_int16_t (*) (configuration_attribute_t *)) get_attribute_length;
|
||||
this->public.destroy = (void (*) (configuration_attribute_t *)) destroy;
|
||||
|
||||
/* set default values of the fields */
|
||||
this->attribute_type = 0;
|
||||
this->attribute_value = CHUNK_INITIALIZER;
|
||||
this->attribute_length = 0;
|
||||
|
||||
return (&(this->public));
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
/**
|
||||
* @file configuration_attribute.h
|
||||
*
|
||||
* @brief Interface of configuration_attribute_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef CONFIGURATION_ATTRIBUTE_H_
|
||||
#define CONFIGURATION_ATTRIBUTE_H_
|
||||
|
||||
#include <types.h>
|
||||
#include <encoding/payloads/payload.h>
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Configuration attribute header length in bytes.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
#define CONFIGURATION_ATTRIBUTE_HEADER_LENGTH 4
|
||||
|
||||
|
||||
typedef enum configuration_attribute_type_t configuration_attribute_type_t;
|
||||
|
||||
/**
|
||||
* Type of the attribute, as in IKEv2 RFC 3.15.1.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
enum configuration_attribute_type_t {
|
||||
INTERNAL_IP4_ADDRESS = 1,
|
||||
INTERNAL_IP4_NETMASK = 2,
|
||||
INTERNAL_IP4_DNS = 3,
|
||||
INTERNAL_IP4_NBNS = 4,
|
||||
INTERNAL_ADDRESS_EXPIRY = 5,
|
||||
INTERNAL_IP4_DHCP = 6,
|
||||
APPLICATION_VERSION = 7,
|
||||
INTERNAL_IP6_ADDRESS = 8,
|
||||
INTERNAL_IP6_DNS = 10,
|
||||
INTERNAL_IP6_NBNS = 11,
|
||||
INTERNAL_IP6_DHCP = 12,
|
||||
INTERNAL_IP4_SUBNET = 13,
|
||||
SUPPORTED_ATTRIBUTES = 14,
|
||||
INTERNAL_IP6_SUBNET = 15
|
||||
};
|
||||
|
||||
/**
|
||||
* String mappings for configuration_attribute_type_t.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
extern mapping_t configuration_attribute_type_m[];
|
||||
|
||||
typedef struct configuration_attribute_t configuration_attribute_t;
|
||||
|
||||
/**
|
||||
* @brief Class representing an IKEv2-CONFIGURATION Attribute.
|
||||
*
|
||||
* The CONFIGURATION ATTRIBUTE format is described in RFC section 3.15.1.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - configuration_attribute_create()
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
struct configuration_attribute_t {
|
||||
/**
|
||||
* The payload_t interface.
|
||||
*/
|
||||
payload_t payload_interface;
|
||||
|
||||
/**
|
||||
* @brief Returns the currently set value of the attribute.
|
||||
*
|
||||
* @warning Returned data are not copied.
|
||||
*
|
||||
* @param this calling configuration_attribute_t object
|
||||
* @return chunk_t pointing to the value
|
||||
*/
|
||||
chunk_t (*get_value) (configuration_attribute_t *this);
|
||||
|
||||
/**
|
||||
* @brief Sets the value of the attribute.
|
||||
*
|
||||
* @warning Value is getting copied.
|
||||
*
|
||||
* @param this calling configuration_attribute_t object
|
||||
* @param value chunk_t pointing to the value to set
|
||||
*/
|
||||
void (*set_value) (configuration_attribute_t *this, chunk_t value);
|
||||
|
||||
/**
|
||||
* @brief Sets the type of the attribute.
|
||||
*
|
||||
* @param this calling configuration_attribute_t object
|
||||
* @param type type to set (most significant bit is set to zero)
|
||||
*/
|
||||
void (*set_attribute_type) (configuration_attribute_t *this, u_int16_t type);
|
||||
|
||||
/**
|
||||
* @brief get the type of the attribute.
|
||||
*
|
||||
* @param this calling configuration_attribute_t object
|
||||
* @return type of the value
|
||||
*/
|
||||
u_int16_t (*get_attribute_type) (configuration_attribute_t *this);
|
||||
|
||||
/**
|
||||
* @brief get the length of an attribute.
|
||||
*
|
||||
* @param this calling configuration_attribute_t object
|
||||
* @return type of the value
|
||||
*/
|
||||
u_int16_t (*get_attribute_length) (configuration_attribute_t *this);
|
||||
|
||||
/**
|
||||
* @brief Destroys an configuration_attribute_t object.
|
||||
*
|
||||
* @param this configuration_attribute_t object to destroy
|
||||
*/
|
||||
void (*destroy) (configuration_attribute_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Creates an empty configuration_attribute_t object.
|
||||
*
|
||||
* @return created configuration_attribute_t object
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
configuration_attribute_t *configuration_attribute_create();
|
||||
|
||||
#endif /* CONFIGURATION_ATTRIBUTE_H_*/
|
||||
@@ -0,0 +1,305 @@
|
||||
/**
|
||||
* @file cp_payload.c
|
||||
*
|
||||
* @brief Implementation of cp_payload_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "cp_payload.h"
|
||||
|
||||
#include <encoding/payloads/encodings.h>
|
||||
#include <utils/linked_list.h>
|
||||
|
||||
|
||||
/**
|
||||
* String mappings for config_type_t.
|
||||
*/
|
||||
mapping_t config_type_m[] = {
|
||||
{CFG_REQUEST, "CFG_REQUEST"},
|
||||
{CFG_REPLY, "CFG_REPLY"},
|
||||
{CFG_SET, "CFG_SET"},
|
||||
{CFG_ACK, "CFG_ACK"},
|
||||
{MAPPING_END, NULL}
|
||||
};
|
||||
|
||||
|
||||
typedef struct private_cp_payload_t private_cp_payload_t;
|
||||
|
||||
/**
|
||||
* Private data of an cp_payload_t object.
|
||||
*
|
||||
*/
|
||||
struct private_cp_payload_t {
|
||||
/**
|
||||
* Public cp_payload_t interface.
|
||||
*/
|
||||
cp_payload_t public;
|
||||
|
||||
/**
|
||||
* Next payload type.
|
||||
*/
|
||||
u_int8_t next_payload;
|
||||
|
||||
/**
|
||||
* Critical flag.
|
||||
*/
|
||||
bool critical;
|
||||
|
||||
/**
|
||||
* Length of this payload.
|
||||
*/
|
||||
u_int16_t payload_length;
|
||||
|
||||
/**
|
||||
* Configuration Attributes in this payload are stored in a linked_list_t.
|
||||
*/
|
||||
linked_list_t * attributes;
|
||||
|
||||
/**
|
||||
* Config Type.
|
||||
*/
|
||||
u_int8_t config_type;
|
||||
|
||||
/**
|
||||
* @brief Computes the length of this payload.
|
||||
*
|
||||
* @param this calling private_cp_payload_t object
|
||||
*/
|
||||
void (*compute_length) (private_cp_payload_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Encoding rules to parse or generate a IKEv2-CP Payload
|
||||
*
|
||||
* The defined offsets are the positions in a object of type
|
||||
* private_cp_payload_t.
|
||||
*
|
||||
*/
|
||||
encoding_rule_t cp_payload_encodings[] = {
|
||||
/* 1 Byte next payload type, stored in the field next_payload */
|
||||
{ U_INT_8, offsetof(private_cp_payload_t, next_payload) },
|
||||
/* the critical bit */
|
||||
{ FLAG, offsetof(private_cp_payload_t, critical) },
|
||||
/* 7 Bit reserved bits, nowhere stored */
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
/* Length of the whole CP payload*/
|
||||
{ PAYLOAD_LENGTH, offsetof(private_cp_payload_t, payload_length) },
|
||||
/* Proposals are stored in a proposal substructure,
|
||||
offset points to a linked_list_t pointer */
|
||||
{ U_INT_8, offsetof(private_cp_payload_t, config_type) },
|
||||
{ RESERVED_BYTE,0 },
|
||||
{ RESERVED_BYTE,0 },
|
||||
{ RESERVED_BYTE,0 },
|
||||
{ CONFIGURATION_ATTRIBUTES, offsetof(private_cp_payload_t, attributes) }
|
||||
};
|
||||
|
||||
/*
|
||||
1 2 3
|
||||
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 !C! RESERVED ! Payload Length !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! CFG Type ! RESERVED !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! !
|
||||
~ Configuration Attributes ~
|
||||
! !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.verify.
|
||||
*/
|
||||
static status_t verify(private_cp_payload_t *this)
|
||||
{
|
||||
status_t status = SUCCESS;
|
||||
iterator_t *iterator;
|
||||
|
||||
iterator = this->attributes->create_iterator(this->attributes,TRUE);
|
||||
|
||||
while(iterator->has_next(iterator))
|
||||
{
|
||||
configuration_attribute_t *attribute;
|
||||
iterator->current(iterator,(void **)&attribute);
|
||||
status = attribute->payload_interface.verify(&(attribute->payload_interface));
|
||||
if (status != SUCCESS)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
iterator->destroy(iterator);
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_encoding_rules.
|
||||
*/
|
||||
static void get_encoding_rules(private_cp_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
|
||||
{
|
||||
*rules = cp_payload_encodings;
|
||||
*rule_count = sizeof(cp_payload_encodings) / sizeof(encoding_rule_t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_type.
|
||||
*/
|
||||
static payload_type_t get_type(private_cp_payload_t *this)
|
||||
{
|
||||
return CONFIGURATION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_next_type.
|
||||
*/
|
||||
static payload_type_t get_next_type(private_cp_payload_t *this)
|
||||
{
|
||||
return (this->next_payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.set_next_type.
|
||||
*/
|
||||
static void set_next_type(private_cp_payload_t *this,payload_type_t type)
|
||||
{
|
||||
this->next_payload = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_length.
|
||||
*/
|
||||
static size_t get_length(private_cp_payload_t *this)
|
||||
{
|
||||
this->compute_length(this);
|
||||
return this->payload_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of cp_payload_t.create_configuration_attribute_iterator.
|
||||
*/
|
||||
static iterator_t *create_configuration_attribute_iterator (private_cp_payload_t *this,bool forward)
|
||||
{
|
||||
return this->attributes->create_iterator(this->attributes,forward);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of cp_payload_t.add_proposal_substructure.
|
||||
*/
|
||||
static void add_configuration_attribute (private_cp_payload_t *this,configuration_attribute_t *attribute)
|
||||
{
|
||||
this->attributes->insert_last(this->attributes,(void *) attribute);
|
||||
this->compute_length(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of cp_payload_t.set_config_type.
|
||||
*/
|
||||
static void set_config_type (private_cp_payload_t *this,config_type_t config_type)
|
||||
{
|
||||
this->config_type = config_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of cp_payload_t.get_config_type.
|
||||
*/
|
||||
static config_type_t get_config_type (private_cp_payload_t *this)
|
||||
{
|
||||
return this->config_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of private_cp_payload_t.compute_length.
|
||||
*/
|
||||
static void compute_length (private_cp_payload_t *this)
|
||||
{
|
||||
iterator_t *iterator;
|
||||
size_t length = CP_PAYLOAD_HEADER_LENGTH;
|
||||
iterator = this->attributes->create_iterator(this->attributes,TRUE);
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
payload_t *current_attribute;
|
||||
iterator->current(iterator,(void **) ¤t_attribute);
|
||||
length += current_attribute->get_length(current_attribute);
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
this->payload_length = length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.destroy and cp_payload_t.destroy.
|
||||
*/
|
||||
static status_t destroy(private_cp_payload_t *this)
|
||||
{
|
||||
/* all attributes are getting destroyed */
|
||||
while (this->attributes->get_count(this->attributes) > 0)
|
||||
{
|
||||
configuration_attribute_t *current_attribute;
|
||||
this->attributes->remove_last(this->attributes,(void **)¤t_attribute);
|
||||
current_attribute->destroy(current_attribute);
|
||||
}
|
||||
this->attributes->destroy(this->attributes);
|
||||
|
||||
free(this);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
cp_payload_t *cp_payload_create()
|
||||
{
|
||||
private_cp_payload_t *this = malloc_thing(private_cp_payload_t);
|
||||
|
||||
/* public interface */
|
||||
this->public.payload_interface.verify = (status_t (*) (payload_t *))verify;
|
||||
this->public.payload_interface.get_encoding_rules = (void (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules;
|
||||
this->public.payload_interface.get_length = (size_t (*) (payload_t *)) get_length;
|
||||
this->public.payload_interface.get_next_type = (payload_type_t (*) (payload_t *)) get_next_type;
|
||||
this->public.payload_interface.set_next_type = (void (*) (payload_t *,payload_type_t)) set_next_type;
|
||||
this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_type;
|
||||
this->public.payload_interface.destroy = (void (*) (payload_t *))destroy;
|
||||
|
||||
/* public functions */
|
||||
this->public.create_configuration_attribute_iterator = (iterator_t* (*) (cp_payload_t *,bool)) create_configuration_attribute_iterator;
|
||||
this->public.add_configuration_attribute = (void (*) (cp_payload_t *,configuration_attribute_t *)) add_configuration_attribute;
|
||||
this->public.set_config_type = (void (*) (cp_payload_t *, config_type_t)) set_config_type;
|
||||
this->public.get_config_type = (config_type_t (*) (cp_payload_t *)) get_config_type;
|
||||
this->public.destroy = (void (*) (cp_payload_t *)) destroy;
|
||||
|
||||
|
||||
/* private functions */
|
||||
this->compute_length = compute_length;
|
||||
|
||||
/* set default values of the fields */
|
||||
this->critical = FALSE;
|
||||
this->next_payload = NO_PAYLOAD;
|
||||
this->payload_length = CP_PAYLOAD_HEADER_LENGTH;
|
||||
|
||||
this->attributes = linked_list_create();
|
||||
return (&(this->public));
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
/**
|
||||
* @file cp_payload.h
|
||||
*
|
||||
* @brief Interface of cp_payload_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef CP_PAYLOAD_H_
|
||||
#define CP_PAYLOAD_H_
|
||||
|
||||
#include <types.h>
|
||||
#include <encoding/payloads/payload.h>
|
||||
#include <encoding/payloads/configuration_attribute.h>
|
||||
#include <utils/linked_list.h>
|
||||
|
||||
/**
|
||||
* CP_PAYLOAD length in bytes without any proposal substructure.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
#define CP_PAYLOAD_HEADER_LENGTH 8
|
||||
|
||||
|
||||
typedef enum config_type_t config_type_t;
|
||||
|
||||
/**
|
||||
* Config Type of an Configuration Payload.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
enum config_type_t {
|
||||
CFG_REQUEST = 1,
|
||||
CFG_REPLY = 2,
|
||||
CFG_SET = 3,
|
||||
CFG_ACK = 4,
|
||||
};
|
||||
|
||||
/**
|
||||
* string mappings for config_type_t.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
extern mapping_t config_type_m[];
|
||||
|
||||
|
||||
typedef struct cp_payload_t cp_payload_t;
|
||||
|
||||
/**
|
||||
* @brief Class representing an IKEv2-CP Payload.
|
||||
*
|
||||
* The CP Payload format is described in RFC section 3.15.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - cp_payload_create()
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
struct cp_payload_t {
|
||||
/**
|
||||
* The payload_t interface.
|
||||
*/
|
||||
payload_t payload_interface;
|
||||
|
||||
/**
|
||||
* @brief Creates an iterator of stored configuration_attribute_t objects.
|
||||
*
|
||||
* @warning The created iterator has to get destroyed by the caller!
|
||||
*
|
||||
* @warning When deleting an attribute using this iterator,
|
||||
* the length of this configuration_attribute_t has to be refreshed
|
||||
* by calling get_length()!
|
||||
*
|
||||
* @param this calling cp_payload_t object
|
||||
* @param[in] forward iterator direction (TRUE: front to end)
|
||||
* @return created iterator_t object
|
||||
*/
|
||||
iterator_t *(*create_configuration_attribute_iterator) (cp_payload_t *this, bool forward);
|
||||
|
||||
/**
|
||||
* @brief Adds a configuration_attribute_t object to this object.
|
||||
*
|
||||
* @warning The added configuration_attribute_t object is
|
||||
* getting destroyed in destroy function of cp_payload_t.
|
||||
*
|
||||
* @param this calling cp_payload_t object
|
||||
* @param attribute configuration_attribute_t object to add
|
||||
*/
|
||||
void (*add_configuration_attribute) (cp_payload_t *this, configuration_attribute_t *attribute);
|
||||
|
||||
/**
|
||||
* @brief Set the config type.
|
||||
*
|
||||
* @param this calling cp_payload_t object
|
||||
* @param config_type config_type_t to set
|
||||
*/
|
||||
void (*set_config_type) (cp_payload_t *this,config_type_t config_type);
|
||||
|
||||
/**
|
||||
* @brief Get the config type.
|
||||
*
|
||||
* @param this calling cp_payload_t object
|
||||
* @return config_type_t
|
||||
*/
|
||||
config_type_t (*get_config_type) (cp_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Destroys an cp_payload_t object.
|
||||
*
|
||||
* @param this cp_payload_t object to destroy
|
||||
*/
|
||||
void (*destroy) (cp_payload_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Creates an empty cp_payload_t object
|
||||
*
|
||||
* @return cp_payload_t object
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
cp_payload_t *cp_payload_create();
|
||||
|
||||
#endif /*CP_PAYLOAD_H_*/
|
||||
@@ -0,0 +1,322 @@
|
||||
/**
|
||||
* @file delete_payload.c
|
||||
*
|
||||
* @brief Implementation of delete_payload_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "delete_payload.h"
|
||||
|
||||
|
||||
typedef struct private_delete_payload_t private_delete_payload_t;
|
||||
|
||||
/**
|
||||
* Private data of an delete_payload_t object.
|
||||
*
|
||||
*/
|
||||
struct private_delete_payload_t {
|
||||
/**
|
||||
* Public delete_payload_t interface.
|
||||
*/
|
||||
delete_payload_t public;
|
||||
|
||||
/**
|
||||
* Next payload type.
|
||||
*/
|
||||
u_int8_t next_payload;
|
||||
|
||||
/**
|
||||
* Critical flag.
|
||||
*/
|
||||
bool critical;
|
||||
|
||||
/**
|
||||
* Length of this payload.
|
||||
*/
|
||||
u_int16_t payload_length;
|
||||
|
||||
/**
|
||||
* Protocol ID.
|
||||
*/
|
||||
u_int8_t protocol_id;
|
||||
|
||||
/**
|
||||
* SPI Size.
|
||||
*/
|
||||
u_int8_t spi_size;
|
||||
|
||||
/**
|
||||
* Number of SPI's.
|
||||
*/
|
||||
u_int16_t spi_count;
|
||||
|
||||
/**
|
||||
* The contained SPI's.
|
||||
*/
|
||||
chunk_t spis;
|
||||
};
|
||||
|
||||
/**
|
||||
* Encoding rules to parse or generate a DELETE payload
|
||||
*
|
||||
* The defined offsets are the positions in a object of type
|
||||
* private_delete_payload_t.
|
||||
*
|
||||
*/
|
||||
encoding_rule_t delete_payload_encodings[] = {
|
||||
/* 1 Byte next payload type, stored in the field next_payload */
|
||||
{ U_INT_8, offsetof(private_delete_payload_t, next_payload) },
|
||||
/* the critical bit */
|
||||
{ FLAG, offsetof(private_delete_payload_t, critical) },
|
||||
/* 7 Bit reserved bits, nowhere stored */
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
/* Length of the whole payload*/
|
||||
{ PAYLOAD_LENGTH, offsetof(private_delete_payload_t, payload_length)},
|
||||
{ U_INT_8, offsetof(private_delete_payload_t, protocol_id) },
|
||||
{ U_INT_8, offsetof(private_delete_payload_t, spi_size) },
|
||||
{ U_INT_16, offsetof(private_delete_payload_t, spi_count) },
|
||||
/* some delete data bytes, length is defined in PAYLOAD_LENGTH */
|
||||
{ SPIS, offsetof(private_delete_payload_t, spis) }
|
||||
};
|
||||
|
||||
/*
|
||||
1 2 3
|
||||
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 !C! RESERVED ! Payload Length !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! Protocol ID ! SPI Size ! # of SPIs !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! !
|
||||
~ Security Parameter Index(es) (SPI) ~
|
||||
! !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.verify.
|
||||
*/
|
||||
static status_t verify(private_delete_payload_t *this)
|
||||
{
|
||||
if ((this->protocol_id == 0) ||
|
||||
(this->protocol_id > 3))
|
||||
{
|
||||
/* reserved IDs */
|
||||
return FAILED;
|
||||
}
|
||||
if (this->spis.len != (this->spi_count * this->spi_size))
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
if ((this->protocol_id == PROTO_IKE) && (this->spis.len != 0))
|
||||
{
|
||||
/* IKE deletion has no spi assigned! */
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of delete_payload_t.get_encoding_rules.
|
||||
*/
|
||||
static void get_encoding_rules(private_delete_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
|
||||
{
|
||||
*rules = delete_payload_encodings;
|
||||
*rule_count = sizeof(delete_payload_encodings) / sizeof(encoding_rule_t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_type.
|
||||
*/
|
||||
static payload_type_t get_payload_type(private_delete_payload_t *this)
|
||||
{
|
||||
return DELETE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_next_type.
|
||||
*/
|
||||
static payload_type_t get_next_type(private_delete_payload_t *this)
|
||||
{
|
||||
return (this->next_payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.set_next_type.
|
||||
*/
|
||||
static void set_next_type(private_delete_payload_t *this,payload_type_t type)
|
||||
{
|
||||
this->next_payload = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_length.
|
||||
*/
|
||||
static size_t get_length(private_delete_payload_t *this)
|
||||
{
|
||||
return this->payload_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of delete_payload_t.set_protocol_id.
|
||||
*/
|
||||
static void set_protocol_id (private_delete_payload_t *this, protocol_id_t protocol_id)
|
||||
{
|
||||
this->protocol_id = protocol_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of delete_payload_t.get_protocol_id.
|
||||
*/
|
||||
static protocol_id_t get_protocol_id (private_delete_payload_t *this)
|
||||
{
|
||||
return (this->protocol_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of delete_payload_t.set_spi_size.
|
||||
*/
|
||||
static void set_spi_size (private_delete_payload_t *this, u_int8_t spi_size)
|
||||
{
|
||||
this->spi_size = spi_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of delete_payload_t.get_spi_size.
|
||||
*/
|
||||
static u_int8_t get_spi_size (private_delete_payload_t *this)
|
||||
{
|
||||
return (this->spi_size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of delete_payload_t.set_spi_count.
|
||||
*/
|
||||
static void set_spi_count (private_delete_payload_t *this, u_int16_t spi_count)
|
||||
{
|
||||
this->spi_count = spi_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of delete_payload_t.get_spi_count.
|
||||
*/
|
||||
static u_int16_t get_spi_count (private_delete_payload_t *this)
|
||||
{
|
||||
return (this->spi_count);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of delete_payload_t.set_spis.
|
||||
*/
|
||||
static void set_spis (private_delete_payload_t *this, chunk_t spis)
|
||||
{
|
||||
if (this->spis.ptr != NULL)
|
||||
{
|
||||
chunk_free(&(this->spis));
|
||||
}
|
||||
this->spis.ptr = clalloc(spis.ptr,spis.len);
|
||||
this->spis.len = spis.len;
|
||||
this->payload_length = DELETE_PAYLOAD_HEADER_LENGTH + this->spis.len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of delete_payload_t.get_spis.
|
||||
*/
|
||||
static chunk_t get_spis (private_delete_payload_t *this)
|
||||
{
|
||||
return (this->spis);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of delete_payload_t.get_spis_clone.
|
||||
*/
|
||||
static chunk_t get_spis_clone (private_delete_payload_t *this)
|
||||
{
|
||||
chunk_t cloned_spis;
|
||||
if (this->spis.ptr == NULL)
|
||||
{
|
||||
return (this->spis);
|
||||
}
|
||||
cloned_spis.ptr = clalloc(this->spis.ptr,this->spis.len);
|
||||
cloned_spis.len = this->spis.len;
|
||||
return cloned_spis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.destroy and delete_payload_t.destroy.
|
||||
*/
|
||||
static void destroy(private_delete_payload_t *this)
|
||||
{
|
||||
if (this->spis.ptr != NULL)
|
||||
{
|
||||
chunk_free(&(this->spis));
|
||||
}
|
||||
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
delete_payload_t *delete_payload_create()
|
||||
{
|
||||
private_delete_payload_t *this = malloc_thing(private_delete_payload_t);
|
||||
|
||||
/* interface functions */
|
||||
this->public.payload_interface.verify = (status_t (*) (payload_t *))verify;
|
||||
this->public.payload_interface.get_encoding_rules = (void (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules;
|
||||
this->public.payload_interface.get_length = (size_t (*) (payload_t *)) get_length;
|
||||
this->public.payload_interface.get_next_type = (payload_type_t (*) (payload_t *)) get_next_type;
|
||||
this->public.payload_interface.set_next_type = (void (*) (payload_t *,payload_type_t)) set_next_type;
|
||||
this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_payload_type;
|
||||
this->public.payload_interface.destroy = (void (*) (payload_t *))destroy;
|
||||
|
||||
/* public functions */
|
||||
this->public.destroy = (void (*) (delete_payload_t *)) destroy;
|
||||
this->public.set_protocol_id = (void (*) (delete_payload_t *,protocol_id_t)) set_protocol_id;
|
||||
this->public.get_protocol_id = (protocol_id_t (*) (delete_payload_t *)) get_protocol_id;
|
||||
this->public.set_spi_size = (void (*) (delete_payload_t *,u_int8_t)) set_spi_size;
|
||||
this->public.get_spi_size = (u_int8_t (*) (delete_payload_t *)) get_spi_size;
|
||||
this->public.set_spi_count = (void (*) (delete_payload_t *,u_int16_t)) set_spi_count;
|
||||
this->public.get_spi_count = (u_int16_t (*) (delete_payload_t *)) get_spi_count;
|
||||
this->public.set_spis = (void (*) (delete_payload_t *,chunk_t)) set_spis;
|
||||
this->public.get_spis_clone = (chunk_t (*) (delete_payload_t *)) get_spis_clone;
|
||||
this->public.get_spis = (chunk_t (*) (delete_payload_t *)) get_spis;
|
||||
|
||||
/* private variables */
|
||||
this->critical = FALSE;
|
||||
this->next_payload = NO_PAYLOAD;
|
||||
this->payload_length =DELETE_PAYLOAD_HEADER_LENGTH;
|
||||
this->protocol_id = PROTO_NONE;
|
||||
this->spi_size = 0;
|
||||
this->spi_count = 0;
|
||||
this->spis = CHUNK_INITIALIZER;
|
||||
|
||||
return (&(this->public));
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
/**
|
||||
* @file delete_payload.h
|
||||
*
|
||||
* @brief Interface of delete_payload_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef DELETE_PAYLOAD_H_
|
||||
#define DELETE_PAYLOAD_H_
|
||||
|
||||
#include <types.h>
|
||||
#include <encoding/payloads/payload.h>
|
||||
#include <encoding/payloads/proposal_substructure.h>
|
||||
|
||||
/**
|
||||
* Length of a delete payload without the SPI in bytes.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
#define DELETE_PAYLOAD_HEADER_LENGTH 8
|
||||
|
||||
|
||||
|
||||
typedef struct delete_payload_t delete_payload_t;
|
||||
|
||||
/**
|
||||
* @brief Class representing an IKEv2 DELETE payload.
|
||||
*
|
||||
* The DELETE payload format is described in RFC section 3.11.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - delete_payload_create()
|
||||
*
|
||||
* @todo Implement better setter/getters
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
struct delete_payload_t {
|
||||
/**
|
||||
* The payload_t interface.
|
||||
*/
|
||||
payload_t payload_interface;
|
||||
|
||||
/**
|
||||
* @brief Set the protocol ID.
|
||||
*
|
||||
* @param this calling delete_payload_t object
|
||||
* @param protocol_id protocol ID
|
||||
*/
|
||||
void (*set_protocol_id) (delete_payload_t *this, protocol_id_t protocol_id);
|
||||
|
||||
/**
|
||||
* @brief Get the protocol ID.
|
||||
*
|
||||
* @param this calling delete_payload_t object
|
||||
* @return protocol ID
|
||||
*/
|
||||
protocol_id_t (*get_protocol_id) (delete_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Set the SPI size.
|
||||
*
|
||||
*
|
||||
* @param this calling delete_payload_t object
|
||||
* @param spi_size SPI size
|
||||
*/
|
||||
void (*set_spi_size) (delete_payload_t *this, u_int8_t spi_size);
|
||||
|
||||
/**
|
||||
* @brief Get the SPI size.
|
||||
*
|
||||
* @param this calling delete_payload_t object
|
||||
* @return SPI size
|
||||
*/
|
||||
u_int8_t (*get_spi_size) (delete_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Set the SPI count.
|
||||
*
|
||||
* @param this calling delete_payload_t object
|
||||
* @param spi_count SPI count
|
||||
*/
|
||||
void (*set_spi_count) (delete_payload_t *this, u_int16_t spi_count);
|
||||
|
||||
/**
|
||||
* @brief Get the SPI count.
|
||||
*
|
||||
* @param this calling delete_payload_t object
|
||||
* @return Number of SPI's
|
||||
*/
|
||||
u_int16_t (*get_spi_count) (delete_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Set the SPI's.
|
||||
*
|
||||
* Data are getting cloned.
|
||||
*
|
||||
* @param this calling delete_payload_t object
|
||||
* @param data SPI's as chunk_t
|
||||
*/
|
||||
void (*set_spis) (delete_payload_t *this, chunk_t spis);
|
||||
|
||||
/**
|
||||
* @brief Get the SPI's.
|
||||
*
|
||||
* Returned data are a copy of the internal one.
|
||||
*
|
||||
* @param this calling delete_payload_t object
|
||||
* @return SPI's chunk_t
|
||||
*/
|
||||
chunk_t (*get_spis_clone) (delete_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get the SPI's.
|
||||
*
|
||||
* Returned data are NOT copied.
|
||||
*
|
||||
* @param this calling delete_payload_t object
|
||||
* @return SPI's as chunk_t
|
||||
*/
|
||||
chunk_t (*get_spis) (delete_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Destroys an delete_payload_t object.
|
||||
*
|
||||
* @param this delete_payload_t object to destroy
|
||||
*/
|
||||
void (*destroy) (delete_payload_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Creates an empty delete_payload_t object.
|
||||
*
|
||||
* @return delete_payload_t object
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
delete_payload_t *delete_payload_create();
|
||||
|
||||
|
||||
#endif /* DELETE_PAYLOAD_H_ */
|
||||
@@ -0,0 +1,227 @@
|
||||
/**
|
||||
* @file eap_payload.c
|
||||
*
|
||||
* @brief Implementation of eap_payload_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "eap_payload.h"
|
||||
|
||||
|
||||
typedef struct private_eap_payload_t private_eap_payload_t;
|
||||
|
||||
/**
|
||||
* Private data of an eap_payload_t object.
|
||||
*
|
||||
*/
|
||||
struct private_eap_payload_t {
|
||||
/**
|
||||
* Public eap_payload_t interface.
|
||||
*/
|
||||
eap_payload_t public;
|
||||
|
||||
/**
|
||||
* Next payload type.
|
||||
*/
|
||||
u_int8_t next_payload;
|
||||
|
||||
/**
|
||||
* Critical flag.
|
||||
*/
|
||||
bool critical;
|
||||
|
||||
/**
|
||||
* Length of this payload.
|
||||
*/
|
||||
u_int16_t payload_length;
|
||||
|
||||
/**
|
||||
* The contained message.
|
||||
*/
|
||||
chunk_t message;
|
||||
};
|
||||
|
||||
/**
|
||||
* Encoding rules to parse or generate a EAP payload.
|
||||
*
|
||||
* The defined offsets are the positions in a object of type
|
||||
* private_eap_payload_t.
|
||||
*
|
||||
*/
|
||||
encoding_rule_t eap_payload_encodings[] = {
|
||||
/* 1 Byte next payload type, stored in the field next_payload */
|
||||
{ U_INT_8, offsetof(private_eap_payload_t, next_payload) },
|
||||
/* the critical bit */
|
||||
{ FLAG, offsetof(private_eap_payload_t, critical) },
|
||||
/* 7 Bit reserved bits, nowhere stored */
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
/* Length of the whole payload*/
|
||||
{ PAYLOAD_LENGTH, offsetof(private_eap_payload_t, payload_length)},
|
||||
/* some eap data bytes, length is defined in PAYLOAD_LENGTH */
|
||||
{ EAP_MESSAGE, offsetof(private_eap_payload_t, message) }
|
||||
};
|
||||
|
||||
/*
|
||||
1 2 3
|
||||
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 !C! RESERVED ! Payload Length !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! !
|
||||
~ EAP Message ~
|
||||
! !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.verify.
|
||||
*/
|
||||
static status_t verify(private_eap_payload_t *this)
|
||||
{
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of eap_payload_t.get_encoding_rules.
|
||||
*/
|
||||
static void get_encoding_rules(private_eap_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
|
||||
{
|
||||
*rules = eap_payload_encodings;
|
||||
*rule_count = sizeof(eap_payload_encodings) / sizeof(encoding_rule_t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_type.
|
||||
*/
|
||||
static payload_type_t get_payload_type(private_eap_payload_t *this)
|
||||
{
|
||||
return EXTENSIBLE_AUTHENTICATION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_next_type.
|
||||
*/
|
||||
static payload_type_t get_next_type(private_eap_payload_t *this)
|
||||
{
|
||||
return (this->next_payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.set_next_type.
|
||||
*/
|
||||
static void set_next_type(private_eap_payload_t *this,payload_type_t type)
|
||||
{
|
||||
this->next_payload = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_length.
|
||||
*/
|
||||
static size_t get_length(private_eap_payload_t *this)
|
||||
{
|
||||
return this->payload_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of eap_payload_t.set_message.
|
||||
*/
|
||||
static void set_message (private_eap_payload_t *this, chunk_t message)
|
||||
{
|
||||
if (this->message.ptr != NULL)
|
||||
{
|
||||
chunk_free(&(this->message));
|
||||
}
|
||||
this->message.ptr = clalloc(message.ptr,message.len);
|
||||
this->message.len = message.len;
|
||||
this->payload_length = EAP_PAYLOAD_HEADER_LENGTH + this->message.len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of eap_payload_t.get_message.
|
||||
*/
|
||||
static chunk_t get_message (private_eap_payload_t *this)
|
||||
{
|
||||
return (this->message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of eap_payload_t.get_data_clone.
|
||||
*/
|
||||
static chunk_t get_message_clone (private_eap_payload_t *this)
|
||||
{
|
||||
chunk_t cloned_message;
|
||||
if (this->message.ptr == NULL)
|
||||
{
|
||||
return (this->message);
|
||||
}
|
||||
cloned_message.ptr = clalloc(this->message.ptr,this->message.len);
|
||||
cloned_message.len = this->message.len;
|
||||
return cloned_message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.destroy and eap_payload_t.destroy.
|
||||
*/
|
||||
static void destroy(private_eap_payload_t *this)
|
||||
{
|
||||
if (this->message.ptr != NULL)
|
||||
{
|
||||
chunk_free(&(this->message));
|
||||
}
|
||||
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
eap_payload_t *eap_payload_create()
|
||||
{
|
||||
private_eap_payload_t *this = malloc_thing(private_eap_payload_t);
|
||||
|
||||
/* interface functions */
|
||||
this->public.payload_interface.verify = (status_t (*) (payload_t *))verify;
|
||||
this->public.payload_interface.get_encoding_rules = (void (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules;
|
||||
this->public.payload_interface.get_length = (size_t (*) (payload_t *)) get_length;
|
||||
this->public.payload_interface.get_next_type = (payload_type_t (*) (payload_t *)) get_next_type;
|
||||
this->public.payload_interface.set_next_type = (void (*) (payload_t *,payload_type_t)) set_next_type;
|
||||
this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_payload_type;
|
||||
this->public.payload_interface.destroy = (void (*) (payload_t *))destroy;
|
||||
|
||||
/* public functions */
|
||||
this->public.destroy = (void (*) (eap_payload_t *)) destroy;
|
||||
this->public.set_message = (void (*) (eap_payload_t *,chunk_t)) set_message;
|
||||
this->public.get_message_clone = (chunk_t (*) (eap_payload_t *)) get_message_clone;
|
||||
this->public.get_message = (chunk_t (*) (eap_payload_t *)) get_message;
|
||||
|
||||
/* private variables */
|
||||
this->critical = FALSE;
|
||||
this->next_payload = NO_PAYLOAD;
|
||||
this->payload_length = EAP_PAYLOAD_HEADER_LENGTH;
|
||||
this->message = CHUNK_INITIALIZER;
|
||||
|
||||
return (&(this->public));
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
/**
|
||||
* @file eap_payload.h
|
||||
*
|
||||
* @brief Interface of eap_payload_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef EAP_PAYLOAD_H_
|
||||
#define EAP_PAYLOAD_H_
|
||||
|
||||
#include <types.h>
|
||||
#include <encoding/payloads/payload.h>
|
||||
|
||||
/**
|
||||
* Length of a EAP payload without the EAP Message in bytes.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
#define EAP_PAYLOAD_HEADER_LENGTH 4
|
||||
|
||||
|
||||
typedef struct eap_payload_t eap_payload_t;
|
||||
|
||||
/**
|
||||
* @brief Class representing an IKEv2 EAP payload.
|
||||
*
|
||||
* The EAP payload format is described in RFC section 3.16.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - eap_payload_create()
|
||||
*
|
||||
* @todo Implement functionality for this payload
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
struct eap_payload_t {
|
||||
/**
|
||||
* The payload_t interface.
|
||||
*/
|
||||
payload_t payload_interface;
|
||||
|
||||
/**
|
||||
* @brief Set the EAP Message.
|
||||
*
|
||||
* Data are getting cloned.
|
||||
*
|
||||
* @param this calling eap_payload_t object
|
||||
* @param message EAP message as chunk_t
|
||||
*/
|
||||
void (*set_message) (eap_payload_t *this, chunk_t message);
|
||||
|
||||
/**
|
||||
* @brief Get the EAP message.
|
||||
*
|
||||
* Returned data are a copy of the internal one.
|
||||
*
|
||||
* @param this calling eap_payload_t object
|
||||
* @return EAP message as chunk_t
|
||||
*/
|
||||
chunk_t (*get_message_clone) (eap_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get the EAP message.
|
||||
*
|
||||
* Returned data are NOT copied.
|
||||
*
|
||||
* @param this calling eap_payload_t object
|
||||
* @return EAP message as chunk_t
|
||||
*/
|
||||
chunk_t (*get_message) (eap_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Destroys an eap_payload_t object.
|
||||
*
|
||||
* @param this eap_payload_t object to destroy
|
||||
*/
|
||||
void (*destroy) (eap_payload_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Creates an empty eap_payload_t object.
|
||||
*
|
||||
* @return eap_payload_t object
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
eap_payload_t *eap_payload_create();
|
||||
|
||||
|
||||
#endif /* EAP_PAYLOAD_H_ */
|
||||
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* @file encodings.c
|
||||
*
|
||||
* @brief String mappings of encoding_type_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
|
||||
#include "encodings.h"
|
||||
|
||||
|
||||
mapping_t encoding_type_m[] = {
|
||||
{U_INT_4, "U_INT_4"},
|
||||
{U_INT_8, "U_INT_8"},
|
||||
{U_INT_16, "U_INT_16"},
|
||||
{U_INT_32, "U_INT_32"},
|
||||
{U_INT_64, "U_INT_64"},
|
||||
{IKE_SPI, "IKE_SPI"},
|
||||
{RESERVED_BIT, "RESERVED_BIT"},
|
||||
{RESERVED_BYTE, "RESERVED_BYTE"},
|
||||
{FLAG, "FLAG"},
|
||||
{PAYLOAD_LENGTH, "PAYLOAD_LENGTH"},
|
||||
{HEADER_LENGTH, "HEADER_LENGTH"},
|
||||
{SPI_SIZE, "SPI_SIZE"},
|
||||
{SPI, "SPI"},
|
||||
{KEY_EXCHANGE_DATA, "KEY_EXCHANGE_DATA"},
|
||||
{NOTIFICATION_DATA, "NOTIFICATION_DATA"},
|
||||
{PROPOSALS, "PROPOSALS"},
|
||||
{TRANSFORMS, "TRANSFORMS"},
|
||||
{TRANSFORM_ATTRIBUTES, "TRANSFORM_ATTRIBUTES"},
|
||||
{ATTRIBUTE_FORMAT, "ATTRIBUTE_FORMAT"},
|
||||
{ATTRIBUTE_TYPE, "ATTRIBUTE_TYPE"},
|
||||
{ATTRIBUTE_LENGTH_OR_VALUE, "ATTRIBUTE_LENGTH_OR_VALUE"},
|
||||
{ATTRIBUTE_VALUE, "ATTRIBUTE_VALUE"},
|
||||
{NONCE_DATA, "NONCE_DATA"},
|
||||
{ID_DATA, "ID_DATA"},
|
||||
{AUTH_DATA, "AUTH_DATA"},
|
||||
{ENCRYPTED_DATA, "ENCRYPTED_DATA"},
|
||||
{TS_TYPE, "TS_TYPE"},
|
||||
{ADDRESS, "ADDRESS"},
|
||||
{TRAFFIC_SELECTORS, "TRAFFIC_SELECTORS"},
|
||||
{CERT_DATA, "CERT_DATA"},
|
||||
{CERTREQ_DATA, "CERTREQ_DATA"},
|
||||
{SPIS, "SPIS"},
|
||||
{VID_DATA, "VID_DATA"},
|
||||
{VID_DATA, "VID_DATA"},
|
||||
{CONFIGURATION_ATTRIBUTES, "CONFIGURATION_ATTRIBUTES"},
|
||||
{CONFIGURATION_ATTRIBUTE_LENGTH, "CONFIGURATION_ATTRIBUTE_LENGTH"},
|
||||
{CONFIGURATION_ATTRIBUTE_VALUE, "CONFIGURATION_ATTRIBUTE_VALUE"},
|
||||
{EAP_MESSAGE, "EAP_MESSAGE"},
|
||||
{UNKNOWN_DATA,"UNKNOWN_DATA"},
|
||||
{MAPPING_END, NULL}
|
||||
};
|
||||
@@ -0,0 +1,540 @@
|
||||
/**
|
||||
* @file encodings.h
|
||||
*
|
||||
* @brief Definition of encoding_type_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef ENCODINGS_H_
|
||||
#define ENCODINGS_H_
|
||||
|
||||
#include <types.h>
|
||||
#include <definitions.h>
|
||||
|
||||
|
||||
typedef enum encoding_type_t encoding_type_t;
|
||||
|
||||
/**
|
||||
* @brief All different kinds of encoding types.
|
||||
*
|
||||
* Each field of an IKEv2-Message (in header or payload)
|
||||
* which has to be parsed or generated differently has its own
|
||||
* type defined here.
|
||||
*
|
||||
* Header is parsed like a payload and gets its one payload_id
|
||||
* from PRIVATE USE space. Also the substructures
|
||||
* of specific payload types get their own payload_id
|
||||
* from PRIVATE_USE space. See IKEv2-Draft for more informations.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
enum encoding_type_t {
|
||||
|
||||
/**
|
||||
* Representing a 4 Bit unsigned int value.
|
||||
*
|
||||
*
|
||||
* When generating it must be changed from host to network order.
|
||||
* The value is read from the associated data struct.
|
||||
* The current write position is moved 4 bit forward afterwards.
|
||||
*
|
||||
* When parsing it must be changed from network to host order.
|
||||
* The value is written to the associated data struct.
|
||||
* The current read pointer is moved 4 bit forward afterwards.
|
||||
*/
|
||||
U_INT_4,
|
||||
|
||||
/**
|
||||
* Representing a 8 Bit unsigned int value.
|
||||
*
|
||||
*
|
||||
* When generating it must be changed from host to network order.
|
||||
* The value is read from the associated data struct.
|
||||
* The current write position is moved 8 bit forward afterwards.
|
||||
*
|
||||
* When parsing it must be changed from network to host order.
|
||||
* The value is written to the associated data struct.
|
||||
* The current read pointer is moved 8 bit forward afterwards.
|
||||
*/
|
||||
U_INT_8,
|
||||
|
||||
/**
|
||||
* Representing a 16 Bit unsigned int value.
|
||||
*
|
||||
*
|
||||
* When generating it must be changed from host to network order.
|
||||
* The value is read from the associated data struct.
|
||||
* The current write position is moved 16 bit forward afterwards.
|
||||
*
|
||||
* When parsing it must be changed from network to host order.
|
||||
* The value is written to the associated data struct.
|
||||
* The current read pointer is moved 16 bit forward afterwards.
|
||||
*/
|
||||
U_INT_16,
|
||||
|
||||
/**
|
||||
* Representing a 32 Bit unsigned int value.
|
||||
*
|
||||
* When generating it must be changed from host to network order.
|
||||
* The value is read from the associated data struct.
|
||||
* The current write position is moved 32 bit forward afterwards.
|
||||
*
|
||||
* When parsing it must be changed from network to host order.
|
||||
* The value is written to the associated data struct.
|
||||
* The current read pointer is moved 32 bit forward afterwards.
|
||||
*/
|
||||
U_INT_32,
|
||||
|
||||
/**
|
||||
* Representing a 64 Bit unsigned int value.
|
||||
*
|
||||
* When generating it must be changed from host to network order.
|
||||
* The value is read from the associated data struct.
|
||||
* The current write position is moved 64 bit forward afterwards.
|
||||
*
|
||||
* When parsing it must be changed from network to host order.
|
||||
* The value is written to the associated data struct.
|
||||
* The current read pointer is moved 64 bit forward afterwards.
|
||||
*/
|
||||
U_INT_64,
|
||||
|
||||
/**
|
||||
* @brief represents a RESERVED_BIT used in FLAG-Bytes.
|
||||
*
|
||||
* When generating, the next bit is set to zero and the current write
|
||||
* position is moved one bit forward.
|
||||
* No value is read from the associated data struct.
|
||||
* The current write position is moved 1 bit forward afterwards.
|
||||
*
|
||||
* When parsing, the current read pointer is moved one bit forward.
|
||||
* No value is written to the associated data struct.
|
||||
* The current read pointer is moved 1 bit forward afterwards.
|
||||
*/
|
||||
RESERVED_BIT,
|
||||
|
||||
/**
|
||||
* @brief represents a RESERVED_BYTE.
|
||||
*
|
||||
* When generating, the next byte is set to zero and the current write
|
||||
* position is moved one byte forward.
|
||||
* No value is read from the associated data struct.
|
||||
* The current write position is moved 1 byte forward afterwards.
|
||||
*
|
||||
* When parsing, the current read pointer is moved one byte forward.
|
||||
* No value is written to the associated data struct.
|
||||
* The current read pointer is moved 1 byte forward afterwards.
|
||||
*/
|
||||
RESERVED_BYTE,
|
||||
|
||||
/**
|
||||
* Representing a 1 Bit flag.
|
||||
*
|
||||
* When generation, the next bit is set to 1 if the associated value
|
||||
* in the data struct is TRUE, 0 otherwise. The current write position
|
||||
* is moved 1 bit forward afterwards.
|
||||
*
|
||||
* When parsing, the next bit is read and stored in the associated data
|
||||
* struct. 0 means FALSE, 1 means TRUE, The current read pointer
|
||||
* is moved 1 bit forward afterwards
|
||||
*/
|
||||
FLAG,
|
||||
|
||||
/**
|
||||
* Representating a length field of a payload.
|
||||
*
|
||||
* When generating it must be changed from host to network order.
|
||||
* The value is read from the associated data struct.
|
||||
* The current write position is moved 16 bit forward afterwards.
|
||||
*
|
||||
* When parsing it must be changed from network to host order.
|
||||
* The value is written to the associated data struct.
|
||||
* The current read pointer is moved 16 bit forward afterwards.
|
||||
*/
|
||||
PAYLOAD_LENGTH,
|
||||
|
||||
/**
|
||||
* Representating a length field of a header.
|
||||
*
|
||||
* When generating it must be changed from host to network order.
|
||||
* The value is read from the associated data struct.
|
||||
* The current write position is moved 32 bit forward afterwards.
|
||||
*
|
||||
* When parsing it must be changed from network to host order.
|
||||
* The value is written to the associated data struct.
|
||||
* The current read pointer is moved 32 bit forward afterwards.
|
||||
*/
|
||||
HEADER_LENGTH,
|
||||
|
||||
/**
|
||||
* Representating a spi size field.
|
||||
*
|
||||
* When generating it must be changed from host to network order.
|
||||
* The value is read from the associated data struct.
|
||||
* The current write position is moved 8 bit forward afterwards.
|
||||
*
|
||||
* When parsing it must be changed from network to host order.
|
||||
* The value is written to the associated data struct.
|
||||
* The current read pointer is moved 8 bit forward afterwards.
|
||||
*/
|
||||
SPI_SIZE,
|
||||
|
||||
/**
|
||||
* Representating a spi field.
|
||||
*
|
||||
* When generating the content of the chunkt pointing to
|
||||
* is written.
|
||||
*
|
||||
* When parsing SPI_SIZE bytes are read and written into the chunk pointing to.
|
||||
*/
|
||||
SPI,
|
||||
|
||||
/**
|
||||
* Representating a Key Exchange Data field.
|
||||
*
|
||||
* When generating the content of the chunkt pointing to
|
||||
* is written.
|
||||
*
|
||||
* When parsing (Payload Length - 8) bytes are read and written into the chunk pointing to.
|
||||
*/
|
||||
KEY_EXCHANGE_DATA,
|
||||
|
||||
/**
|
||||
* Representating a Notification field.
|
||||
*
|
||||
* When generating the content of the chunkt pointing to
|
||||
* is written.
|
||||
*
|
||||
* When parsing (Payload Length - spi size - 8) bytes are read and written into the chunk pointing to.
|
||||
*/
|
||||
NOTIFICATION_DATA,
|
||||
|
||||
/**
|
||||
* Representating one or more proposal substructures.
|
||||
*
|
||||
* The offset points to a linked_list_t pointer.
|
||||
*
|
||||
* When generating the proposal_substructure_t objects are stored
|
||||
* in the pointed linked_list.
|
||||
*
|
||||
* When parsing the parsed proposal_substructure_t objects have
|
||||
* to be stored in the pointed linked_list.
|
||||
*/
|
||||
PROPOSALS,
|
||||
|
||||
/**
|
||||
* Representating one or more transform substructures.
|
||||
*
|
||||
* The offset points to a linked_list_t pointer.
|
||||
*
|
||||
* When generating the transform_substructure_t objects are stored
|
||||
* in the pointed linked_list.
|
||||
*
|
||||
* When parsing the parsed transform_substructure_t objects have
|
||||
* to be stored in the pointed linked_list.
|
||||
*/
|
||||
TRANSFORMS,
|
||||
|
||||
/**
|
||||
* Representating one or more Attributes of a transform substructure.
|
||||
*
|
||||
* The offset points to a linked_list_t pointer.
|
||||
*
|
||||
* When generating the transform_attribute_t objects are stored
|
||||
* in the pointed linked_list.
|
||||
*
|
||||
* When parsing the parsed transform_attribute_t objects have
|
||||
* to be stored in the pointed linked_list.
|
||||
*/
|
||||
TRANSFORM_ATTRIBUTES,
|
||||
|
||||
/**
|
||||
* Representating one or more Attributes of a configuration payload.
|
||||
*
|
||||
* The offset points to a linked_list_t pointer.
|
||||
*
|
||||
* When generating the configuration_attribute_t objects are stored
|
||||
* in the pointed linked_list.
|
||||
*
|
||||
* When parsing the parsed configuration_attribute_t objects have
|
||||
* to be stored in the pointed linked_list.
|
||||
*/
|
||||
CONFIGURATION_ATTRIBUTES,
|
||||
|
||||
/**
|
||||
*
|
||||
* When generating the content of the chunkt pointing to
|
||||
* is written.
|
||||
*
|
||||
* When parsing (Payload Length - 4) bytes are read and written into the chunk pointing to.
|
||||
*/
|
||||
CONFIGURATION_ATTRIBUTE_VALUE,
|
||||
|
||||
/**
|
||||
* Representing a 1 Bit flag specifying the format of a transform attribute.
|
||||
*
|
||||
* When generation, the next bit is set to 1 if the associated value
|
||||
* in the data struct is TRUE, 0 otherwise. The current write position
|
||||
* is moved 1 bit forward afterwards.
|
||||
*
|
||||
* When parsing, the next bit is read and stored in the associated data
|
||||
* struct. 0 means FALSE, 1 means TRUE, The current read pointer
|
||||
* is moved 1 bit forward afterwards.
|
||||
*/
|
||||
ATTRIBUTE_FORMAT,
|
||||
/**
|
||||
* Representing a 15 Bit unsigned int value used as attribute type
|
||||
* in an attribute transform.
|
||||
*
|
||||
*
|
||||
* When generating it must be changed from host to network order.
|
||||
* The value is read from the associated data struct.
|
||||
* The current write position is moved 15 bit forward afterwards.
|
||||
*
|
||||
* When parsing it must be changed from network to host order.
|
||||
* The value is written to the associated data struct.
|
||||
* The current read pointer is moved 15 bit forward afterwards.
|
||||
*/
|
||||
ATTRIBUTE_TYPE,
|
||||
|
||||
/**
|
||||
* Depending on the field of type ATTRIBUTE_FORMAT
|
||||
* this field contains the length or the value of an transform attribute.
|
||||
* Its stored in a 16 unsigned integer field.
|
||||
*
|
||||
* When generating it must be changed from host to network order.
|
||||
* The value is read from the associated data struct.
|
||||
* The current write position is moved 16 bit forward afterwards.
|
||||
*
|
||||
* When parsing it must be changed from network to host order.
|
||||
* The value is written to the associated data struct.
|
||||
* The current read pointer is moved 16 bit forward afterwards.
|
||||
*/
|
||||
ATTRIBUTE_LENGTH_OR_VALUE,
|
||||
|
||||
/**
|
||||
* This field contains the length or the value of an configuration attribute.
|
||||
* Its stored in a 16 unsigned integer field.
|
||||
*
|
||||
* When generating it must be changed from host to network order.
|
||||
* The value is read from the associated data struct.
|
||||
* The current write position is moved 16 bit forward afterwards.
|
||||
*
|
||||
* When parsing it must be changed from network to host order.
|
||||
* The value is written to the associated data struct.
|
||||
* The current read pointer is moved 16 bit forward afterwards.
|
||||
*/
|
||||
CONFIGURATION_ATTRIBUTE_LENGTH,
|
||||
|
||||
/**
|
||||
* Depending on the field of type ATTRIBUTE_FORMAT
|
||||
* this field is available or missing and so parsed/generated
|
||||
* or not parsed/not generated.
|
||||
*
|
||||
* When generating the content of the chunkt pointing to
|
||||
* is written.
|
||||
*
|
||||
* When parsing SPI_SIZE bytes are read and written into the chunk pointing to.
|
||||
*/
|
||||
ATTRIBUTE_VALUE,
|
||||
|
||||
/**
|
||||
* Representating one or more Traffic selectors of a TS payload.
|
||||
*
|
||||
* The offset points to a linked_list_t pointer.
|
||||
*
|
||||
* When generating the traffic_selector_substructure_t objects are stored
|
||||
* in the pointed linked_list.
|
||||
*
|
||||
* When parsing the parsed traffic_selector_substructure_t objects have
|
||||
* to be stored in the pointed linked_list.
|
||||
*/
|
||||
TRAFFIC_SELECTORS,
|
||||
|
||||
/**
|
||||
* Representating a Traffic selector type field.
|
||||
*
|
||||
* When generating it must be changed from host to network order.
|
||||
* The value is read from the associated data struct.
|
||||
* The current write position is moved 16 bit forward afterwards.
|
||||
*
|
||||
* When parsing it must be changed from network to host order.
|
||||
* The value is written to the associated data struct.
|
||||
* The current read pointer is moved 16 bit forward afterwards.
|
||||
*/
|
||||
TS_TYPE,
|
||||
|
||||
/**
|
||||
* Representating an address field in a traffic selector.
|
||||
*
|
||||
* Depending on the last field of type TS_TYPE
|
||||
* this field is either 4 or 16 byte long.
|
||||
*
|
||||
* When generating the content of the chunkt pointing to
|
||||
* is written.
|
||||
*
|
||||
* When parsing 4 or 16 bytes are read and written into the chunk pointing to.
|
||||
*/
|
||||
ADDRESS,
|
||||
|
||||
/**
|
||||
* Representating a Nonce Data field.
|
||||
*
|
||||
* When generating the content of the chunkt pointing to
|
||||
* is written.
|
||||
*
|
||||
* When parsing (Payload Length - 4) bytes are read and written into the chunk pointing to.
|
||||
*/
|
||||
NONCE_DATA,
|
||||
|
||||
/**
|
||||
* Representating a ID Data field.
|
||||
*
|
||||
* When generating the content of the chunkt pointing to
|
||||
* is written.
|
||||
*
|
||||
* When parsing (Payload Length - 8) bytes are read and written into the chunk pointing to.
|
||||
*/
|
||||
ID_DATA,
|
||||
|
||||
/**
|
||||
* Representating a AUTH Data field.
|
||||
*
|
||||
* When generating the content of the chunkt pointing to
|
||||
* is written.
|
||||
*
|
||||
* When parsing (Payload Length - 8) bytes are read and written into the chunk pointing to.
|
||||
*/
|
||||
AUTH_DATA,
|
||||
|
||||
/**
|
||||
* Representating a CERT Data field.
|
||||
*
|
||||
* When generating the content of the chunkt pointing to
|
||||
* is written.
|
||||
*
|
||||
* When parsing (Payload Length - 5) bytes are read and written into the chunk pointing to.
|
||||
*/
|
||||
CERT_DATA,
|
||||
|
||||
/**
|
||||
* Representating a CERTREQ Data field.
|
||||
*
|
||||
* When generating the content of the chunkt pointing to
|
||||
* is written.
|
||||
*
|
||||
* When parsing (Payload Length - 5) bytes are read and written into the chunk pointing to.
|
||||
*/
|
||||
CERTREQ_DATA,
|
||||
|
||||
/**
|
||||
* Representating an EAP message field.
|
||||
*
|
||||
* When generating the content of the chunkt pointing to
|
||||
* is written.
|
||||
*
|
||||
* When parsing (Payload Length - 4) bytes are read and written into the chunk pointing to.
|
||||
*/
|
||||
EAP_MESSAGE,
|
||||
|
||||
/**
|
||||
* Representating the SPIS field in a DELETE payload.
|
||||
*
|
||||
* When generating the content of the chunkt pointing to
|
||||
* is written.
|
||||
*
|
||||
* When parsing (Payload Length - 8) bytes are read and written into the chunk pointing to.
|
||||
*/
|
||||
SPIS,
|
||||
|
||||
/**
|
||||
* Representating the VID DATA field in a VENDOR ID payload.
|
||||
*
|
||||
* When generating the content of the chunkt pointing to
|
||||
* is written.
|
||||
*
|
||||
* When parsing (Payload Length - 4) bytes are read and written into the chunk pointing to.
|
||||
*/
|
||||
VID_DATA,
|
||||
|
||||
/**
|
||||
* Representating the DATA of an unknown payload.
|
||||
*
|
||||
* When generating the content of the chunkt pointing to
|
||||
* is written.
|
||||
*
|
||||
* When parsing (Payload Length - 4) bytes are read and written into the chunk pointing to.
|
||||
*/
|
||||
UNKNOWN_DATA,
|
||||
|
||||
/**
|
||||
* Representating an IKE_SPI field in an IKEv2 Header.
|
||||
*
|
||||
* When generating the value of the u_int64_t pointing to
|
||||
* is written (host and networ order is not changed).
|
||||
*
|
||||
* When parsing 8 bytes are read and written into the u_int64_t pointing to.
|
||||
*/
|
||||
IKE_SPI,
|
||||
|
||||
/**
|
||||
* Representing the encrypted data body of a encryption payload.
|
||||
*/
|
||||
ENCRYPTED_DATA,
|
||||
};
|
||||
|
||||
/**
|
||||
* mappings to map encoding_type_t's to strings
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
extern mapping_t encoding_type_m[];
|
||||
|
||||
|
||||
typedef struct encoding_rule_t encoding_rule_t;
|
||||
|
||||
/**
|
||||
* An encoding rule is a mapping of a specific encoding type to
|
||||
* a location in the data struct where the current field is stored to
|
||||
* or read from.
|
||||
*
|
||||
* For examples see files in this directory.
|
||||
*
|
||||
* This rules are used by parser and generator.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
struct encoding_rule_t {
|
||||
|
||||
/**
|
||||
* Encoding type.
|
||||
*/
|
||||
encoding_type_t type;
|
||||
|
||||
/**
|
||||
* Offset in the data struct.
|
||||
*
|
||||
* When parsing, data are written to this offset of the
|
||||
* data struct.
|
||||
*
|
||||
* When generating, data are read from this offset in the
|
||||
* data struct.
|
||||
*/
|
||||
u_int32_t offset;
|
||||
};
|
||||
|
||||
#endif /*ENCODINGS_H_*/
|
||||
@@ -0,0 +1,702 @@
|
||||
/**
|
||||
* @file encryption_payload.c
|
||||
*
|
||||
* @brief Implementation of encryption_payload_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "encryption_payload.h"
|
||||
|
||||
#include <daemon.h>
|
||||
#include <encoding/payloads/encodings.h>
|
||||
#include <utils/linked_list.h>
|
||||
#include <utils/logger.h>
|
||||
#include <encoding/generator.h>
|
||||
#include <encoding/parser.h>
|
||||
#include <utils/iterator.h>
|
||||
#include <utils/randomizer.h>
|
||||
#include <crypto/signers/signer.h>
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct private_encryption_payload_t private_encryption_payload_t;
|
||||
|
||||
/**
|
||||
* Private data of an encryption_payload_t' Object.
|
||||
*
|
||||
*/
|
||||
struct private_encryption_payload_t {
|
||||
|
||||
/**
|
||||
* Public encryption_payload_t interface.
|
||||
*/
|
||||
encryption_payload_t public;
|
||||
|
||||
/**
|
||||
* There is no next payload for an encryption payload,
|
||||
* since encryption payload MUST be the last one.
|
||||
* next_payload means here the first payload of the
|
||||
* contained, encrypted payload.
|
||||
*/
|
||||
u_int8_t next_payload;
|
||||
|
||||
/**
|
||||
* Critical flag.
|
||||
*/
|
||||
bool critical;
|
||||
|
||||
/**
|
||||
* Length of this payload
|
||||
*/
|
||||
u_int16_t payload_length;
|
||||
|
||||
/**
|
||||
* Chunk containing the iv, data, padding,
|
||||
* and (an eventually not calculated) signature.
|
||||
*/
|
||||
chunk_t encrypted;
|
||||
|
||||
/**
|
||||
* Chunk containing the data in decrypted (unpadded) form.
|
||||
*/
|
||||
chunk_t decrypted;
|
||||
|
||||
/**
|
||||
* Signer set by set_signer.
|
||||
*/
|
||||
signer_t *signer;
|
||||
|
||||
/**
|
||||
* Crypter, supplied by encrypt/decrypt
|
||||
*/
|
||||
crypter_t *crypter;
|
||||
|
||||
/**
|
||||
* Contained payloads of this encrpytion_payload.
|
||||
*/
|
||||
linked_list_t *payloads;
|
||||
|
||||
/**
|
||||
* logger for this payload, uses MESSAGE context
|
||||
*/
|
||||
logger_t *logger;
|
||||
|
||||
/**
|
||||
* @brief Computes the length of this payload.
|
||||
*
|
||||
* @param this calling private_encryption_payload_t object
|
||||
*/
|
||||
void (*compute_length) (private_encryption_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Generate payloads (unencrypted) in chunk decrypted.
|
||||
*
|
||||
* @param this calling private_encryption_payload_t object
|
||||
*/
|
||||
void (*generate) (private_encryption_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Parse payloads from a (unencrypted) chunk.
|
||||
*
|
||||
* @param this calling private_encryption_payload_t object
|
||||
*/
|
||||
status_t (*parse) (private_encryption_payload_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Encoding rules to parse or generate a IKEv2-Encryption Payload.
|
||||
*
|
||||
* The defined offsets are the positions in a object of type
|
||||
* private_encryption_payload_t.
|
||||
*
|
||||
*/
|
||||
encoding_rule_t encryption_payload_encodings[] = {
|
||||
/* 1 Byte next payload type, stored in the field next_payload */
|
||||
{ U_INT_8, offsetof(private_encryption_payload_t, next_payload) },
|
||||
/* the critical bit */
|
||||
{ FLAG, offsetof(private_encryption_payload_t, critical) },
|
||||
/* 7 Bit reserved bits, nowhere stored */
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
/* Length of the whole encryption payload*/
|
||||
{ PAYLOAD_LENGTH, offsetof(private_encryption_payload_t, payload_length) },
|
||||
/* encrypted data, stored in a chunk. contains iv, data, padding */
|
||||
{ ENCRYPTED_DATA, offsetof(private_encryption_payload_t, encrypted) },
|
||||
};
|
||||
|
||||
/*
|
||||
1 2 3
|
||||
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 !C! RESERVED ! Payload Length !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! Initialization Vector !
|
||||
! (length is block size for encryption algorithm) !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! Encrypted IKE Payloads !
|
||||
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! ! Padding (0-255 octets) !
|
||||
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
|
||||
! ! Pad Length !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
~ Integrity Checksum Data ~
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.verify.
|
||||
*/
|
||||
static status_t verify(private_encryption_payload_t *this)
|
||||
{
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_encoding_rules.
|
||||
*/
|
||||
static void get_encoding_rules(private_encryption_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
|
||||
{
|
||||
*rules = encryption_payload_encodings;
|
||||
*rule_count = sizeof(encryption_payload_encodings) / sizeof(encoding_rule_t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_type.
|
||||
*/
|
||||
static payload_type_t get_type(private_encryption_payload_t *this)
|
||||
{
|
||||
return ENCRYPTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_next_type.
|
||||
*/
|
||||
static payload_type_t get_next_type(private_encryption_payload_t *this)
|
||||
{
|
||||
/* returns first contained payload here */
|
||||
return (this->next_payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.set_next_type.
|
||||
*/
|
||||
static void set_next_type(private_encryption_payload_t *this, payload_type_t type)
|
||||
{
|
||||
/* set next type is not allowed, since this payload MUST be the last one
|
||||
* and so nothing is done in here*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_length.
|
||||
*/
|
||||
static size_t get_length(private_encryption_payload_t *this)
|
||||
{
|
||||
this->compute_length(this);
|
||||
return this->payload_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.create_payload_iterator.
|
||||
*/
|
||||
static iterator_t *create_payload_iterator (private_encryption_payload_t *this, bool forward)
|
||||
{
|
||||
return (this->payloads->create_iterator(this->payloads, forward));
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.add_payload.
|
||||
*/
|
||||
static void add_payload(private_encryption_payload_t *this, payload_t *payload)
|
||||
{
|
||||
payload_t *last_payload;
|
||||
if (this->payloads->get_count(this->payloads) > 0)
|
||||
{
|
||||
this->payloads->get_last(this->payloads,(void **) &last_payload);
|
||||
last_payload->set_next_type(last_payload, payload->get_type(payload));
|
||||
}
|
||||
else
|
||||
{
|
||||
this->next_payload = payload->get_type(payload);
|
||||
}
|
||||
payload->set_next_type(payload, NO_PAYLOAD);
|
||||
this->payloads->insert_last(this->payloads, (void*)payload);
|
||||
this->compute_length(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of encryption_payload_t.remove_first_payload.
|
||||
*/
|
||||
static status_t remove_first_payload(private_encryption_payload_t *this, payload_t **payload)
|
||||
{
|
||||
return this->payloads->remove_first(this->payloads, (void**)payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of encryption_payload_t.get_payload_count.
|
||||
*/
|
||||
static size_t get_payload_count(private_encryption_payload_t *this)
|
||||
{
|
||||
return this->payloads->get_count(this->payloads);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of encryption_payload_t.encrypt.
|
||||
*/
|
||||
static status_t encrypt(private_encryption_payload_t *this)
|
||||
{
|
||||
chunk_t iv, padding, to_crypt, result;
|
||||
randomizer_t *randomizer;
|
||||
status_t status;
|
||||
size_t block_size;
|
||||
|
||||
if (this->signer == NULL || this->crypter == NULL)
|
||||
{
|
||||
this->logger->log(this->logger, ERROR, "could not encrypt, signer/crypter not set");
|
||||
return INVALID_STATE;
|
||||
}
|
||||
|
||||
/* for random data in iv and padding */
|
||||
randomizer = randomizer_create();
|
||||
|
||||
|
||||
/* build payload chunk */
|
||||
this->generate(this);
|
||||
|
||||
this->logger->log(this->logger, CONTROL|LEVEL2, "encrypting payloads");
|
||||
this->logger->log_chunk(this->logger, RAW|LEVEL2, "data to encrypt", this->decrypted);
|
||||
|
||||
/* build padding */
|
||||
block_size = this->crypter->get_block_size(this->crypter);
|
||||
padding.len = block_size - ((this->decrypted.len + 1) % block_size);
|
||||
status = randomizer->allocate_pseudo_random_bytes(randomizer, padding.len, &padding);
|
||||
if (status != SUCCESS)
|
||||
{
|
||||
randomizer->destroy(randomizer);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* concatenate payload data, padding, padding len */
|
||||
to_crypt.len = this->decrypted.len + padding.len + 1;
|
||||
to_crypt.ptr = malloc(to_crypt.len);
|
||||
|
||||
memcpy(to_crypt.ptr, this->decrypted.ptr, this->decrypted.len);
|
||||
memcpy(to_crypt.ptr + this->decrypted.len, padding.ptr, padding.len);
|
||||
*(to_crypt.ptr + to_crypt.len - 1) = padding.len;
|
||||
|
||||
/* build iv */
|
||||
iv.len = block_size;
|
||||
status = randomizer->allocate_pseudo_random_bytes(randomizer, iv.len, &iv);
|
||||
randomizer->destroy(randomizer);
|
||||
if (status != SUCCESS)
|
||||
{
|
||||
chunk_free(&to_crypt);
|
||||
chunk_free(&padding);
|
||||
return status;
|
||||
}
|
||||
|
||||
this->logger->log_chunk(this->logger, RAW|LEVEL2, "data before encryption with padding", to_crypt);
|
||||
|
||||
/* encrypt to_crypt chunk */
|
||||
free(this->encrypted.ptr);
|
||||
status = this->crypter->encrypt(this->crypter, to_crypt, iv, &result);
|
||||
free(padding.ptr);
|
||||
free(to_crypt.ptr);
|
||||
if (status != SUCCESS)
|
||||
{
|
||||
this->logger->log(this->logger, ERROR|LEVEL1, "encryption failed");
|
||||
free(iv.ptr);
|
||||
return status;
|
||||
}
|
||||
this->logger->log_chunk(this->logger, RAW|LEVEL2, "data after encryption", result);
|
||||
|
||||
|
||||
/* build encrypted result with iv and signature */
|
||||
this->encrypted.len = iv.len + result.len + this->signer->get_block_size(this->signer);
|
||||
free(this->encrypted.ptr);
|
||||
this->encrypted.ptr = malloc(this->encrypted.len);
|
||||
|
||||
/* fill in result, signature is left out */
|
||||
memcpy(this->encrypted.ptr, iv.ptr, iv.len);
|
||||
memcpy(this->encrypted.ptr + iv.len, result.ptr, result.len);
|
||||
|
||||
free(result.ptr);
|
||||
free(iv.ptr);
|
||||
this->logger->log_chunk(this->logger, RAW|LEVEL2, "data after encryption with IV and (invalid) signature", this->encrypted);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of encryption_payload_t.encrypt.
|
||||
*/
|
||||
static status_t decrypt(private_encryption_payload_t *this)
|
||||
{
|
||||
chunk_t iv, concatenated;
|
||||
u_int8_t padding_length;
|
||||
status_t status;
|
||||
|
||||
|
||||
this->logger->log(this->logger, CONTROL|LEVEL2, "decrypting encryption payload");
|
||||
this->logger->log_chunk(this->logger, RAW|LEVEL2, "data before decryption with IV and (invalid) signature", this->encrypted);
|
||||
|
||||
|
||||
if (this->signer == NULL || this->crypter == NULL)
|
||||
{
|
||||
this->logger->log(this->logger, ERROR, "could not decrypt, no crypter/signer set");
|
||||
return INVALID_STATE;
|
||||
}
|
||||
|
||||
/* get IV */
|
||||
iv.len = this->crypter->get_block_size(this->crypter);
|
||||
|
||||
iv.ptr = this->encrypted.ptr;
|
||||
|
||||
/* point concatenated to data + padding + padding_length*/
|
||||
concatenated.ptr = this->encrypted.ptr + iv.len;
|
||||
concatenated.len = this->encrypted.len - iv.len - this->signer->get_block_size(this->signer);
|
||||
|
||||
/* check the size of input:
|
||||
* concatenated must be at least on block_size of crypter
|
||||
*/
|
||||
if (concatenated.len < iv.len)
|
||||
{
|
||||
this->logger->log(this->logger, ERROR|LEVEL1, "could not decrypt, invalid input");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
/* free previus data, if any */
|
||||
free(this->decrypted.ptr);
|
||||
|
||||
this->logger->log_chunk(this->logger, RAW|LEVEL2, "data before decryption", concatenated);
|
||||
|
||||
status = this->crypter->decrypt(this->crypter, concatenated, iv, &(this->decrypted));
|
||||
if (status != SUCCESS)
|
||||
{
|
||||
this->logger->log(this->logger, ERROR|LEVEL1, "could not decrypt, decryption failed");
|
||||
return FAILED;
|
||||
}
|
||||
this->logger->log_chunk(this->logger, RAW|LEVEL2, "data after decryption with padding", this->decrypted);
|
||||
|
||||
|
||||
/* get padding length, sits just bevore signature */
|
||||
padding_length = *(this->decrypted.ptr + this->decrypted.len - 1);
|
||||
/* add one byte to the padding length, since the padding_length field is not included */
|
||||
padding_length++;
|
||||
this->decrypted.len -= padding_length;
|
||||
|
||||
/* check size again */
|
||||
if (padding_length > concatenated.len || this->decrypted.len < 0)
|
||||
{
|
||||
this->logger->log(this->logger, ERROR|LEVEL1, "decryption failed, invalid padding length found. Invalid key?");
|
||||
/* decryption failed :-/ */
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
/* free padding */
|
||||
this->decrypted.ptr = realloc(this->decrypted.ptr, this->decrypted.len);
|
||||
this->logger->log_chunk(this->logger, RAW|LEVEL2, "data after decryption without padding", this->decrypted);
|
||||
this->logger->log(this->logger, CONTROL|LEVEL2, "decryption successful, trying to parse content");
|
||||
return (this->parse(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of encryption_payload_t.set_transforms.
|
||||
*/
|
||||
static void set_transforms(private_encryption_payload_t *this, crypter_t* crypter, signer_t* signer)
|
||||
{
|
||||
this->signer = signer;
|
||||
this->crypter = crypter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of encryption_payload_t.build_signature.
|
||||
*/
|
||||
static status_t build_signature(private_encryption_payload_t *this, chunk_t data)
|
||||
{
|
||||
chunk_t data_without_sig = data;
|
||||
chunk_t sig;
|
||||
|
||||
if (this->signer == NULL)
|
||||
{
|
||||
this->logger->log(this->logger, ERROR, "unable to build signature, no signer set");
|
||||
return INVALID_STATE;
|
||||
}
|
||||
|
||||
sig.len = this->signer->get_block_size(this->signer);
|
||||
data_without_sig.len -= sig.len;
|
||||
sig.ptr = data.ptr + data_without_sig.len;
|
||||
this->logger->log(this->logger, CONTROL|LEVEL2, "building signature");
|
||||
this->signer->get_signature(this->signer, data_without_sig, sig.ptr);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of encryption_payload_t.verify_signature.
|
||||
*/
|
||||
static status_t verify_signature(private_encryption_payload_t *this, chunk_t data)
|
||||
{
|
||||
chunk_t sig, data_without_sig;
|
||||
bool valid;
|
||||
|
||||
if (this->signer == NULL)
|
||||
{
|
||||
this->logger->log(this->logger, ERROR, "unable to verify signature, no signer set");
|
||||
return INVALID_STATE;
|
||||
}
|
||||
/* find signature in data chunk */
|
||||
sig.len = this->signer->get_block_size(this->signer);
|
||||
if (data.len <= sig.len)
|
||||
{
|
||||
this->logger->log(this->logger, ERROR|LEVEL1, "unable to verify signature, invalid input");
|
||||
return FAILED;
|
||||
}
|
||||
sig.ptr = data.ptr + data.len - sig.len;
|
||||
|
||||
/* verify it */
|
||||
data_without_sig.len = data.len - sig.len;
|
||||
data_without_sig.ptr = data.ptr;
|
||||
valid = this->signer->verify_signature(this->signer, data_without_sig, sig);
|
||||
|
||||
if (!valid)
|
||||
{
|
||||
this->logger->log(this->logger, ERROR|LEVEL1, "signature verification failed");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
this->logger->log(this->logger, CONTROL|LEVEL2, "signature verification successful");
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of private_encryption_payload_t.generate.
|
||||
*/
|
||||
static void generate(private_encryption_payload_t *this)
|
||||
{
|
||||
payload_t *current_payload, *next_payload;
|
||||
generator_t *generator;
|
||||
iterator_t *iterator;
|
||||
|
||||
/* recalculate length before generating */
|
||||
this->compute_length(this);
|
||||
|
||||
/* create iterator */
|
||||
iterator = this->payloads->create_iterator(this->payloads, TRUE);
|
||||
|
||||
/* get first payload */
|
||||
if (iterator->has_next(iterator))
|
||||
{
|
||||
iterator->current(iterator, (void**)¤t_payload);
|
||||
this->next_payload = current_payload->get_type(current_payload);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* no paylads? */
|
||||
this->logger->log(this->logger, CONTROL|LEVEL1, "generating contained payloads, but no available");
|
||||
free(this->decrypted.ptr);
|
||||
this->decrypted = CHUNK_INITIALIZER;
|
||||
iterator->destroy(iterator);
|
||||
return;
|
||||
}
|
||||
|
||||
generator = generator_create();
|
||||
|
||||
/* build all payload, except last */
|
||||
while(iterator->has_next(iterator))
|
||||
{
|
||||
iterator->current(iterator, (void**)&next_payload);
|
||||
current_payload->set_next_type(current_payload, next_payload->get_type(next_payload));
|
||||
generator->generate_payload(generator, current_payload);
|
||||
current_payload = next_payload;
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
/* build last payload */
|
||||
current_payload->set_next_type(current_payload, NO_PAYLOAD);
|
||||
generator->generate_payload(generator, current_payload);
|
||||
|
||||
/* free already generated data */
|
||||
free(this->decrypted.ptr);
|
||||
|
||||
generator->write_to_chunk(generator, &(this->decrypted));
|
||||
generator->destroy(generator);
|
||||
this->logger->log(this->logger, CONTROL|LEVEL1, "successfully generated content in encrpytion payload");
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of private_encryption_payload_t.parse.
|
||||
*/
|
||||
static status_t parse(private_encryption_payload_t *this)
|
||||
{
|
||||
parser_t *parser;
|
||||
status_t status;
|
||||
payload_type_t current_payload_type;
|
||||
|
||||
/* check if there is decrypted data */
|
||||
if (this->decrypted.ptr == NULL)
|
||||
{
|
||||
this->logger->log(this->logger, ERROR, "unable to parse, no input!");
|
||||
return INVALID_STATE;
|
||||
}
|
||||
|
||||
/* build a parser on the decrypted data */
|
||||
parser = parser_create(this->decrypted);
|
||||
|
||||
current_payload_type = this->next_payload;
|
||||
/* parse all payloads */
|
||||
while (current_payload_type != NO_PAYLOAD)
|
||||
{
|
||||
payload_t *current_payload;
|
||||
|
||||
status = parser->parse_payload(parser, current_payload_type, (payload_t**)¤t_payload);
|
||||
if (status != SUCCESS)
|
||||
{
|
||||
parser->destroy(parser);
|
||||
return PARSE_ERROR;
|
||||
}
|
||||
|
||||
status = current_payload->verify(current_payload);
|
||||
if (status != SUCCESS)
|
||||
{
|
||||
this->logger->log(this->logger, ERROR|LEVEL1, "%s verification failed: %s",
|
||||
mapping_find(payload_type_m,current_payload->get_type(current_payload)),
|
||||
mapping_find(status_m, status));
|
||||
current_payload->destroy(current_payload);
|
||||
parser->destroy(parser);
|
||||
return VERIFY_ERROR;
|
||||
}
|
||||
|
||||
/* get next payload type */
|
||||
current_payload_type = current_payload->get_next_type(current_payload);
|
||||
|
||||
this->payloads->insert_last(this->payloads,current_payload);
|
||||
}
|
||||
parser->destroy(parser);
|
||||
this->logger->log(this->logger, CONTROL|LEVEL1, "succesfully parsed content of encryption payload");
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of private_encryption_payload_t.compute_length.
|
||||
*/
|
||||
static void compute_length(private_encryption_payload_t *this)
|
||||
{
|
||||
iterator_t *iterator;
|
||||
size_t block_size, length = 0;
|
||||
iterator = this->payloads->create_iterator(this->payloads, TRUE);
|
||||
|
||||
/* count payload length */
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
payload_t *current_payload;
|
||||
iterator->current(iterator, (void **) ¤t_payload);
|
||||
length += current_payload->get_length(current_payload);
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
if (this->crypter && this->signer)
|
||||
{
|
||||
/* append one byte for padding length */
|
||||
length++;
|
||||
/* append padding */
|
||||
block_size = this->crypter->get_block_size(this->crypter);
|
||||
length += block_size - length % block_size;
|
||||
/* add iv */
|
||||
length += block_size;
|
||||
/* add signature */
|
||||
length += this->signer->get_block_size(this->signer);
|
||||
}
|
||||
length += ENCRYPTION_PAYLOAD_HEADER_LENGTH;
|
||||
this->payload_length = length;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.destroy.
|
||||
*/
|
||||
static void destroy(private_encryption_payload_t *this)
|
||||
{
|
||||
/* all proposals are getting destroyed */
|
||||
while (this->payloads->get_count(this->payloads) > 0)
|
||||
{
|
||||
payload_t *current_payload;
|
||||
this->payloads->remove_last(this->payloads,(void **)¤t_payload);
|
||||
current_payload->destroy(current_payload);
|
||||
}
|
||||
this->payloads->destroy(this->payloads);
|
||||
free(this->encrypted.ptr);
|
||||
free(this->decrypted.ptr);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
encryption_payload_t *encryption_payload_create()
|
||||
{
|
||||
private_encryption_payload_t *this = malloc_thing(private_encryption_payload_t);
|
||||
|
||||
/* payload_t interface functions */
|
||||
this->public.payload_interface.verify = (status_t (*) (payload_t *))verify;
|
||||
this->public.payload_interface.get_encoding_rules = (void (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules;
|
||||
this->public.payload_interface.get_length = (size_t (*) (payload_t *)) get_length;
|
||||
this->public.payload_interface.get_next_type = (payload_type_t (*) (payload_t *)) get_next_type;
|
||||
this->public.payload_interface.set_next_type = (void (*) (payload_t *,payload_type_t)) set_next_type;
|
||||
this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_type;
|
||||
this->public.payload_interface.destroy = (void (*) (payload_t *))destroy;
|
||||
|
||||
/* public functions */
|
||||
this->public.create_payload_iterator = (iterator_t * (*) (encryption_payload_t *,bool)) create_payload_iterator;
|
||||
this->public.add_payload = (void (*) (encryption_payload_t *,payload_t *)) add_payload;
|
||||
this->public.remove_first_payload = (status_t (*)(encryption_payload_t*, payload_t **)) remove_first_payload;
|
||||
this->public.get_payload_count = (size_t (*)(encryption_payload_t*)) get_payload_count;
|
||||
|
||||
this->public.encrypt = (status_t (*) (encryption_payload_t *)) encrypt;
|
||||
this->public.decrypt = (status_t (*) (encryption_payload_t *)) decrypt;
|
||||
this->public.set_transforms = (void (*) (encryption_payload_t*,crypter_t*,signer_t*)) set_transforms;
|
||||
this->public.build_signature = (status_t (*) (encryption_payload_t*, chunk_t)) build_signature;
|
||||
this->public.verify_signature = (status_t (*) (encryption_payload_t*, chunk_t)) verify_signature;
|
||||
this->public.destroy = (void (*) (encryption_payload_t *)) destroy;
|
||||
|
||||
/* private functions */
|
||||
this->compute_length = compute_length;
|
||||
this->generate = generate;
|
||||
this->parse = parse;
|
||||
this->logger = logger_manager->get_logger(logger_manager, ENCRYPTION_PAYLOAD);
|
||||
|
||||
/* set default values of the fields */
|
||||
this->critical = FALSE;
|
||||
this->next_payload = NO_PAYLOAD;
|
||||
this->payload_length = ENCRYPTION_PAYLOAD_HEADER_LENGTH;
|
||||
this->encrypted = CHUNK_INITIALIZER;
|
||||
this->decrypted = CHUNK_INITIALIZER;
|
||||
this->signer = NULL;
|
||||
this->crypter = NULL;
|
||||
this->payloads = linked_list_create();
|
||||
|
||||
return (&(this->public));
|
||||
}
|
||||
@@ -0,0 +1,196 @@
|
||||
/**
|
||||
* @file encryption_payload.h
|
||||
*
|
||||
* @brief Interface of encryption_payload_t.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef ENCRYPTION_PAYLOAD_H_
|
||||
#define ENCRYPTION_PAYLOAD_H_
|
||||
|
||||
#include <types.h>
|
||||
#include <crypto/crypters/crypter.h>
|
||||
#include <crypto/signers/signer.h>
|
||||
#include <encoding/payloads/payload.h>
|
||||
#include <utils/linked_list.h>
|
||||
|
||||
/**
|
||||
* Encrpytion payload length in bytes without IV and following data.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
#define ENCRYPTION_PAYLOAD_HEADER_LENGTH 4
|
||||
|
||||
|
||||
typedef struct encryption_payload_t encryption_payload_t;
|
||||
|
||||
/**
|
||||
* @brief The encryption payload as described in RFC section 3.14.
|
||||
*
|
||||
* Before any crypt/decrypt/sign/verify operation can occur,
|
||||
* the transforms must be set. After that, a parsed encryption payload
|
||||
* can be decrypted, which also will parse the contained payloads.
|
||||
* Encryption is done the same way, added payloads will get generated
|
||||
* and then encrypted.
|
||||
* For signature building, there is the FULL packet needed. Meaning it
|
||||
* must be builded after generation of all payloads and the encryption
|
||||
* of the encryption payload.
|
||||
* Signature verificatin is done before decryption.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - encryption_payload_create()
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
struct encryption_payload_t {
|
||||
/**
|
||||
* Implements payload_t interface.
|
||||
*/
|
||||
payload_t payload_interface;
|
||||
|
||||
/**
|
||||
* @brief Creates an iterator for all contained payloads.
|
||||
*
|
||||
* @warning iterator_t object has to get destroyed by the caller.
|
||||
*
|
||||
* @param this calling encryption_payload_t object
|
||||
* @param[in] forward iterator direction (TRUE: front to end)
|
||||
* return created iterator_t object
|
||||
*/
|
||||
iterator_t *(*create_payload_iterator) (encryption_payload_t *this, bool forward);
|
||||
|
||||
/**
|
||||
* @brief Adds a payload to this encryption payload.
|
||||
*
|
||||
* @param this calling encryption_payload_t object
|
||||
* @param payload payload_t object to add
|
||||
*/
|
||||
void (*add_payload) (encryption_payload_t *this, payload_t *payload);
|
||||
|
||||
/**
|
||||
* @brief Reove the last payload in the contained payload list.
|
||||
*
|
||||
* @param this calling encryption_payload_t object
|
||||
* @param[out] payload removed payload
|
||||
* @return
|
||||
* - SUCCESS, or
|
||||
* - NOT_FOUND if list empty
|
||||
*/
|
||||
status_t (*remove_first_payload) (encryption_payload_t *this, payload_t **payload);
|
||||
|
||||
/**
|
||||
* @brief Get the number of payloads.
|
||||
*
|
||||
* @param this calling encryption_payload_t object
|
||||
* @return number of contained payloads
|
||||
*/
|
||||
size_t (*get_payload_count) (encryption_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Set transforms to use.
|
||||
*
|
||||
* To decryption, encryption, signature building and verifying,
|
||||
* the payload needs a crypter and a signer object.
|
||||
*
|
||||
* @warning Do NOT call this function again after encryption, since
|
||||
* the signer must be the same while encrypting and signature building!
|
||||
*
|
||||
* @param this calling encryption_payload_t
|
||||
* @param crypter crypter_t to use for data de-/encryption
|
||||
* @param signer signer_t to use for data signing/verifying
|
||||
*/
|
||||
void (*set_transforms) (encryption_payload_t *this, crypter_t *crypter, signer_t *signer);
|
||||
|
||||
/**
|
||||
* @brief Generate and encrypt contained payloads.
|
||||
*
|
||||
* This function generates the content for added payloads
|
||||
* and encrypts them. Signature is not built, since we need
|
||||
* additional data (the full message).
|
||||
*
|
||||
* @param this calling encryption_payload_t
|
||||
* @return
|
||||
* - SUCCESS, or
|
||||
* - INVALID_STATE if transforms not set
|
||||
*/
|
||||
status_t (*encrypt) (encryption_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Decrypt and parse contained payloads.
|
||||
*
|
||||
* This function decrypts the contained data. After,
|
||||
* the payloads are parsed internally and are accessible
|
||||
* via the iterator.
|
||||
*
|
||||
* @param this calling encryption_payload_t
|
||||
* @return
|
||||
* - SUCCESS, or
|
||||
* - INVALID_STATE if transforms not set, or
|
||||
* - FAILED if data is invalid
|
||||
*/
|
||||
status_t (*decrypt) (encryption_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Build the signature.
|
||||
*
|
||||
* The signature is built over the FULL message, so the header
|
||||
* and every payload (inclusive this one) must already be generated.
|
||||
* The generated message is supplied via the data paramater.
|
||||
*
|
||||
* @param this calling encryption_payload_t
|
||||
* @param data chunk contains the already generated message
|
||||
* @return
|
||||
* - SUCCESS, or
|
||||
* - INVALID_STATE if transforms not set
|
||||
*/
|
||||
status_t (*build_signature) (encryption_payload_t *this, chunk_t data);
|
||||
|
||||
/**
|
||||
* @brief Verify the signature.
|
||||
*
|
||||
* Since the signature is built over the full message, we need
|
||||
* this data to do the verification. The message data
|
||||
* is supplied via the data argument.
|
||||
*
|
||||
* @param this calling encryption_payload_t
|
||||
* @param data chunk contains the message
|
||||
* @return
|
||||
* - SUCCESS, or
|
||||
* - FAILED if signature invalid, or
|
||||
* - INVALID_STATE if transforms not set
|
||||
*/
|
||||
status_t (*verify_signature) (encryption_payload_t *this, chunk_t data);
|
||||
|
||||
/**
|
||||
* @brief Destroys an encryption_payload_t object.
|
||||
*
|
||||
* @param this encryption_payload_t object to destroy
|
||||
*/
|
||||
void (*destroy) (encryption_payload_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Creates an empty encryption_payload_t object.
|
||||
*
|
||||
* @return encryption_payload_t object
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
encryption_payload_t *encryption_payload_create();
|
||||
|
||||
|
||||
#endif /*ENCRYPTION_PAYLOAD_H_*/
|
||||
@@ -0,0 +1,320 @@
|
||||
/**
|
||||
* @file id_payload.h
|
||||
*
|
||||
* @brief Interface of id_payload_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "id_payload.h"
|
||||
|
||||
#include <encoding/payloads/encodings.h>
|
||||
|
||||
typedef struct private_id_payload_t private_id_payload_t;
|
||||
|
||||
/**
|
||||
* Private data of an id_payload_t object.
|
||||
*
|
||||
*/
|
||||
struct private_id_payload_t {
|
||||
/**
|
||||
* Public id_payload_t interface.
|
||||
*/
|
||||
id_payload_t public;
|
||||
|
||||
/**
|
||||
* TRUE if this ID payload is of type IDi, FALSE for IDr.
|
||||
*/
|
||||
bool is_initiator;
|
||||
|
||||
/**
|
||||
* Next payload type.
|
||||
*/
|
||||
u_int8_t next_payload;
|
||||
|
||||
/**
|
||||
* Critical flag.
|
||||
*/
|
||||
bool critical;
|
||||
|
||||
/**
|
||||
* Length of this payload.
|
||||
*/
|
||||
u_int16_t payload_length;
|
||||
|
||||
/**
|
||||
* Type of the ID Data.
|
||||
*/
|
||||
u_int8_t id_type;
|
||||
|
||||
/**
|
||||
* The contained id data value.
|
||||
*/
|
||||
chunk_t id_data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Encoding rules to parse or generate a ID payload
|
||||
*
|
||||
* The defined offsets are the positions in a object of type
|
||||
* private_id_payload_t.
|
||||
*
|
||||
*/
|
||||
encoding_rule_t id_payload_encodings[] = {
|
||||
/* 1 Byte next payload type, stored in the field next_payload */
|
||||
{ U_INT_8, offsetof(private_id_payload_t, next_payload) },
|
||||
/* the critical bit */
|
||||
{ FLAG, offsetof(private_id_payload_t, critical) },
|
||||
/* 7 Bit reserved bits, nowhere stored */
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
/* Length of the whole payload*/
|
||||
{ PAYLOAD_LENGTH, offsetof(private_id_payload_t, payload_length) },
|
||||
/* 1 Byte ID type*/
|
||||
{ U_INT_8, offsetof(private_id_payload_t, id_type) },
|
||||
/* 3 reserved bytes */
|
||||
{ RESERVED_BYTE, 0 },
|
||||
{ RESERVED_BYTE, 0 },
|
||||
{ RESERVED_BYTE, 0 },
|
||||
/* some id data bytes, length is defined in PAYLOAD_LENGTH */
|
||||
{ ID_DATA, offsetof(private_id_payload_t, id_data) }
|
||||
};
|
||||
|
||||
/*
|
||||
1 2 3
|
||||
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 !C! RESERVED ! Payload Length !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! ID Type ! RESERVED |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! !
|
||||
~ Identification Data ~
|
||||
! !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.verify.
|
||||
*/
|
||||
static status_t verify(private_id_payload_t *this)
|
||||
{
|
||||
if ((this->id_type == 0) ||
|
||||
(this->id_type == 4) ||
|
||||
((this->id_type >= 6) && (this->id_type <= 8)) ||
|
||||
((this->id_type >= 12) && (this->id_type <= 200)))
|
||||
{
|
||||
/* reserved IDs */
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of id_payload_t.get_encoding_rules.
|
||||
*/
|
||||
static void get_encoding_rules(private_id_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
|
||||
{
|
||||
*rules = id_payload_encodings;
|
||||
*rule_count = sizeof(id_payload_encodings) / sizeof(encoding_rule_t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_type.
|
||||
*/
|
||||
static payload_type_t get_payload_type(private_id_payload_t *this)
|
||||
{
|
||||
if (this->is_initiator)
|
||||
{
|
||||
return ID_INITIATOR;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ID_RESPONDER;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_next_type.
|
||||
*/
|
||||
static payload_type_t get_next_type(private_id_payload_t *this)
|
||||
{
|
||||
return (this->next_payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.set_next_type.
|
||||
*/
|
||||
static void set_next_type(private_id_payload_t *this,payload_type_t type)
|
||||
{
|
||||
this->next_payload = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_length.
|
||||
*/
|
||||
static size_t get_length(private_id_payload_t *this)
|
||||
{
|
||||
return this->payload_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of id_payload_t.set_type.
|
||||
*/
|
||||
static void set_id_type (private_id_payload_t *this, id_type_t type)
|
||||
{
|
||||
this->id_type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of id_payload_t.get_id_type.
|
||||
*/
|
||||
static id_type_t get_id_type (private_id_payload_t *this)
|
||||
{
|
||||
return (this->id_type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of id_payload_t.set_data.
|
||||
*/
|
||||
static void set_data (private_id_payload_t *this, chunk_t data)
|
||||
{
|
||||
if (this->id_data.ptr != NULL)
|
||||
{
|
||||
chunk_free(&(this->id_data));
|
||||
}
|
||||
this->id_data.ptr = clalloc(data.ptr,data.len);
|
||||
this->id_data.len = data.len;
|
||||
this->payload_length = ID_PAYLOAD_HEADER_LENGTH + this->id_data.len;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of id_payload_t.get_data_clone.
|
||||
*/
|
||||
static chunk_t get_data (private_id_payload_t *this)
|
||||
{
|
||||
return (this->id_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of id_payload_t.get_data_clone.
|
||||
*/
|
||||
static chunk_t get_data_clone (private_id_payload_t *this)
|
||||
{
|
||||
chunk_t cloned_data;
|
||||
if (this->id_data.ptr == NULL)
|
||||
{
|
||||
return (this->id_data);
|
||||
}
|
||||
cloned_data.ptr = clalloc(this->id_data.ptr,this->id_data.len);
|
||||
cloned_data.len = this->id_data.len;
|
||||
return cloned_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of id_payload_t.get_initiator.
|
||||
*/
|
||||
static bool get_initiator (private_id_payload_t *this)
|
||||
{
|
||||
return (this->is_initiator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of id_payload_t.set_initiator.
|
||||
*/
|
||||
static void set_initiator (private_id_payload_t *this,bool is_initiator)
|
||||
{
|
||||
this->is_initiator = is_initiator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of id_payload_t.get_identification.
|
||||
*/
|
||||
static identification_t *get_identification (private_id_payload_t *this)
|
||||
{
|
||||
return identification_create_from_encoding(this->id_type,this->id_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.destroy and id_payload_t.destroy.
|
||||
*/
|
||||
static void destroy(private_id_payload_t *this)
|
||||
{
|
||||
if (this->id_data.ptr != NULL)
|
||||
{
|
||||
chunk_free(&(this->id_data));
|
||||
}
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
id_payload_t *id_payload_create(bool is_initiator)
|
||||
{
|
||||
private_id_payload_t *this = malloc_thing(private_id_payload_t);
|
||||
|
||||
/* interface functions */
|
||||
this->public.payload_interface.verify = (status_t (*) (payload_t *))verify;
|
||||
this->public.payload_interface.get_encoding_rules = (void (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules;
|
||||
this->public.payload_interface.get_length = (size_t (*) (payload_t *)) get_length;
|
||||
this->public.payload_interface.get_next_type = (payload_type_t (*) (payload_t *)) get_next_type;
|
||||
this->public.payload_interface.set_next_type = (void (*) (payload_t *,payload_type_t)) set_next_type;
|
||||
this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_payload_type;
|
||||
this->public.payload_interface.destroy = (void (*) (payload_t *))destroy;
|
||||
|
||||
/* public functions */
|
||||
this->public.destroy = (void (*) (id_payload_t *)) destroy;
|
||||
this->public.set_id_type = (void (*) (id_payload_t *,id_type_t)) set_id_type;
|
||||
this->public.get_id_type = (id_type_t (*) (id_payload_t *)) get_id_type;
|
||||
this->public.set_data = (void (*) (id_payload_t *,chunk_t)) set_data;
|
||||
this->public.get_data = (chunk_t (*) (id_payload_t *)) get_data;
|
||||
this->public.get_data_clone = (chunk_t (*) (id_payload_t *)) get_data_clone;
|
||||
|
||||
this->public.get_initiator = (bool (*) (id_payload_t *)) get_initiator;
|
||||
this->public.set_initiator = (void (*) (id_payload_t *,bool)) set_initiator;
|
||||
this->public.get_identification = (identification_t * (*) (id_payload_t *this)) get_identification;
|
||||
|
||||
/* private variables */
|
||||
this->critical = FALSE;
|
||||
this->next_payload = NO_PAYLOAD;
|
||||
this->payload_length =ID_PAYLOAD_HEADER_LENGTH;
|
||||
this->id_data = CHUNK_INITIALIZER;
|
||||
this->is_initiator = is_initiator;
|
||||
|
||||
return (&(this->public));
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
id_payload_t *id_payload_create_from_identification(bool is_initiator,identification_t *identification)
|
||||
{
|
||||
id_payload_t *this= id_payload_create(is_initiator);
|
||||
this->set_data(this,identification->get_encoding(identification));
|
||||
this->set_id_type(this,identification->get_type(identification));
|
||||
return this;
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
/**
|
||||
* @file id_payload.h
|
||||
*
|
||||
* @brief Interface of id_payload_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef ID_PAYLOAD_H_
|
||||
#define ID_PAYLOAD_H_
|
||||
|
||||
#include <types.h>
|
||||
#include <utils/identification.h>
|
||||
#include <encoding/payloads/payload.h>
|
||||
|
||||
/**
|
||||
* Length of a id payload without the data in bytes.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
#define ID_PAYLOAD_HEADER_LENGTH 8
|
||||
|
||||
|
||||
typedef struct id_payload_t id_payload_t;
|
||||
|
||||
/**
|
||||
* Object representing an IKEv2 ID payload.
|
||||
*
|
||||
* The ID payload format is described in RFC section 3.5.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - id_payload_create_from_identification()
|
||||
* - id_payload_create()
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
struct id_payload_t {
|
||||
/**
|
||||
* The payload_t interface.
|
||||
*/
|
||||
payload_t payload_interface;
|
||||
|
||||
/**
|
||||
* @brief Set the ID type.
|
||||
*
|
||||
* @param this calling id_payload_t object
|
||||
* @param type Type of ID
|
||||
*/
|
||||
void (*set_id_type) (id_payload_t *this, id_type_t type);
|
||||
|
||||
/**
|
||||
* @brief Get the ID type.
|
||||
*
|
||||
* @param this calling id_payload_t object
|
||||
* @return type of the ID
|
||||
*/
|
||||
id_type_t (*get_id_type) (id_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Set the ID data.
|
||||
*
|
||||
* Data are getting cloned.
|
||||
*
|
||||
* @param this calling id_payload_t object
|
||||
* @param data ID data as chunk_t
|
||||
*/
|
||||
void (*set_data) (id_payload_t *this, chunk_t data);
|
||||
|
||||
/**
|
||||
* @brief Get the ID data.
|
||||
*
|
||||
* Returned data are a copy of the internal one
|
||||
*
|
||||
* @param this calling id_payload_t object
|
||||
* @return ID data as chunk_t
|
||||
*/
|
||||
chunk_t (*get_data_clone) (id_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get the ID data.
|
||||
*
|
||||
* Returned data are NOT copied.
|
||||
*
|
||||
* @param this calling id_payload_t object
|
||||
* @return ID data as chunk_t
|
||||
*/
|
||||
chunk_t (*get_data) (id_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Creates an identification object of this id payload.
|
||||
*
|
||||
* Returned object has to get destroyed by the caller.
|
||||
*
|
||||
* @param this calling id_payload_t object
|
||||
* @return identification_t object
|
||||
*/
|
||||
identification_t *(*get_identification) (id_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get the type of ID payload (IDi or IDr).
|
||||
*
|
||||
* @param this calling id_payload_t object
|
||||
* @return
|
||||
* - TRUE if this payload is of type IDi
|
||||
* - FALSE if this payload is of type IDr
|
||||
*
|
||||
*/
|
||||
bool (*get_initiator) (id_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Set the type of ID payload (IDi or IDr).
|
||||
*
|
||||
* @param this calling id_payload_t object
|
||||
* @param is_initiator
|
||||
* - TRUE if this payload is of type IDi
|
||||
* - FALSE if this payload is of type IDr
|
||||
*
|
||||
*/
|
||||
void (*set_initiator) (id_payload_t *this,bool is_initiator);
|
||||
|
||||
/**
|
||||
* @brief Destroys an id_payload_t object.
|
||||
*
|
||||
* @param this id_payload_t object to destroy
|
||||
*/
|
||||
void (*destroy) (id_payload_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Creates an empty id_payload_t object.
|
||||
*
|
||||
* @param is_initiator
|
||||
* - TRUE if this payload is of type IDi
|
||||
* - FALSE if this payload is of type IDr
|
||||
*
|
||||
* @return id_payload_t object
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
id_payload_t *id_payload_create(bool is_initiator);
|
||||
|
||||
/**
|
||||
* @brief Creates an id_payload_t from an existing identification_t object.
|
||||
*
|
||||
* @param is_initiator
|
||||
* - TRUE if this payload is of type IDi
|
||||
* - FALSE if this payload is of type IDr
|
||||
* @param identification identification_t object
|
||||
* @return id_payload_t object
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
id_payload_t *id_payload_create_from_identification(bool is_initiator,identification_t *identification);
|
||||
|
||||
|
||||
|
||||
#endif /* ID_PAYLOAD_H_ */
|
||||
@@ -0,0 +1,408 @@
|
||||
/**
|
||||
* @file ike_header.c
|
||||
*
|
||||
* @brief Implementation of ike_header_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/* offsetof macro */
|
||||
#include <stddef.h>
|
||||
|
||||
#include "ike_header.h"
|
||||
|
||||
#include <encoding/payloads/encodings.h>
|
||||
|
||||
|
||||
typedef struct private_ike_header_t private_ike_header_t;
|
||||
|
||||
/**
|
||||
* Private data of an ike_header_t object.
|
||||
*
|
||||
*/
|
||||
struct private_ike_header_t {
|
||||
/**
|
||||
* Public interface.
|
||||
*/
|
||||
ike_header_t public;
|
||||
|
||||
/**
|
||||
* SPI of the initiator.
|
||||
*/
|
||||
u_int64_t initiator_spi;
|
||||
|
||||
/**
|
||||
* SPI of the responder.
|
||||
*/
|
||||
u_int64_t responder_spi;
|
||||
|
||||
/**
|
||||
* Next payload type.
|
||||
*/
|
||||
u_int8_t next_payload;
|
||||
/**
|
||||
* IKE major version.
|
||||
*/
|
||||
u_int8_t maj_version;
|
||||
|
||||
/**
|
||||
* IKE minor version.
|
||||
*/
|
||||
u_int8_t min_version;
|
||||
|
||||
/**
|
||||
* Exchange type .
|
||||
*/
|
||||
u_int8_t exchange_type;
|
||||
|
||||
/**
|
||||
* Flags of the Message.
|
||||
*
|
||||
*/
|
||||
struct {
|
||||
/**
|
||||
* Sender is initiator of the associated IKE_SA_INIT-Exchange.
|
||||
*/
|
||||
bool initiator;
|
||||
|
||||
/**
|
||||
* Is protocol supporting higher version?
|
||||
*/
|
||||
bool version;
|
||||
|
||||
/**
|
||||
* TRUE, if this is a response, FALSE if its a Request.
|
||||
*/
|
||||
bool response;
|
||||
} flags;
|
||||
|
||||
/**
|
||||
* Associated Message-ID.
|
||||
*/
|
||||
u_int32_t message_id;
|
||||
|
||||
/**
|
||||
* Length of the whole IKEv2-Message (header and all payloads).
|
||||
*/
|
||||
u_int32_t length;
|
||||
};
|
||||
|
||||
/**
|
||||
* Mappings used to get strings for exchange_type_t.
|
||||
*/
|
||||
mapping_t exchange_type_m[] = {
|
||||
{EXCHANGE_TYPE_UNDEFINED, "EXCHANGE_TYPE_UNDEFINED"},
|
||||
{IKE_SA_INIT, "IKE_SA_INIT"},
|
||||
{IKE_AUTH, "IKE_AUTH"},
|
||||
{CREATE_CHILD_SA, "CREATE_CHILD_SA"},
|
||||
{INFORMATIONAL, "INFORMATIONAL"}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Encoding rules to parse or generate a IKEv2-Header.
|
||||
*
|
||||
* The defined offsets are the positions in a object of type
|
||||
* ike_header_t.
|
||||
*
|
||||
*/
|
||||
encoding_rule_t ike_header_encodings[] = {
|
||||
/* 8 Byte SPI, stored in the field initiator_spi */
|
||||
{ IKE_SPI, offsetof(private_ike_header_t, initiator_spi) },
|
||||
/* 8 Byte SPI, stored in the field responder_spi */
|
||||
{ IKE_SPI, offsetof(private_ike_header_t, responder_spi) },
|
||||
/* 1 Byte next payload type, stored in the field next_payload */
|
||||
{ U_INT_8, offsetof(private_ike_header_t, next_payload) },
|
||||
/* 4 Bit major version, stored in the field maj_version */
|
||||
{ U_INT_4, offsetof(private_ike_header_t, maj_version) },
|
||||
/* 4 Bit minor version, stored in the field min_version */
|
||||
{ U_INT_4, offsetof(private_ike_header_t, min_version) },
|
||||
/* 8 Bit for the exchange type */
|
||||
{ U_INT_8, offsetof(private_ike_header_t, exchange_type) },
|
||||
/* 2 Bit reserved bits, nowhere stored */
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
/* 3 Bit flags, stored in the fields response, version and initiator */
|
||||
{ FLAG, offsetof(private_ike_header_t, flags.response) },
|
||||
{ FLAG, offsetof(private_ike_header_t, flags.version) },
|
||||
{ FLAG, offsetof(private_ike_header_t, flags.initiator) },
|
||||
/* 3 Bit reserved bits, nowhere stored */
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
/* 4 Byte message id, stored in the field message_id */
|
||||
{ U_INT_32, offsetof(private_ike_header_t, message_id) },
|
||||
/* 4 Byte length fied, stored in the field length */
|
||||
{ HEADER_LENGTH, offsetof(private_ike_header_t, length) }
|
||||
};
|
||||
|
||||
|
||||
/* 1 2 3
|
||||
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
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! IKE_SA Initiator's SPI !
|
||||
! !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! IKE_SA Responder's SPI !
|
||||
! !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! Next Payload ! MjVer ! MnVer ! Exchange Type ! Flags !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! Message ID !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! Length !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.verify.
|
||||
*/
|
||||
static status_t verify(private_ike_header_t *this)
|
||||
{
|
||||
if ((this->exchange_type < IKE_SA_INIT) || (this->exchange_type > INFORMATIONAL))
|
||||
{
|
||||
/* unsupported exchange type */
|
||||
return FAILED;
|
||||
}
|
||||
if (this->initiator_spi == 0)
|
||||
{
|
||||
/* initiator spi not set */
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
/* verification of version is not done in here */
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.set_next_type.
|
||||
*/
|
||||
static void set_next_type(payload_t *this,payload_type_t type)
|
||||
{
|
||||
((private_ike_header_t *)this)->next_payload = type;
|
||||
}
|
||||
/**
|
||||
* Implementation of ike_header_t.get_initiator_spi.
|
||||
*/
|
||||
static u_int64_t get_initiator_spi(private_ike_header_t *this)
|
||||
{
|
||||
return this->initiator_spi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ike_header_t.set_initiator_spi.
|
||||
*/
|
||||
static void set_initiator_spi(private_ike_header_t *this, u_int64_t initiator_spi)
|
||||
{
|
||||
this->initiator_spi = initiator_spi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ike_header_t.get_responder_spi.
|
||||
*/
|
||||
static u_int64_t get_responder_spi(private_ike_header_t *this)
|
||||
{
|
||||
return this->responder_spi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ike_header_t.set_responder_spi.
|
||||
*/
|
||||
static void set_responder_spi(private_ike_header_t *this, u_int64_t responder_spi)
|
||||
{
|
||||
this->responder_spi = responder_spi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ike_header_t.get_maj_version.
|
||||
*/
|
||||
static u_int8_t get_maj_version(private_ike_header_t *this)
|
||||
{
|
||||
return this->maj_version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ike_header_t.get_min_version.
|
||||
*/
|
||||
static u_int8_t get_min_version(private_ike_header_t *this)
|
||||
{
|
||||
return this->min_version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ike_header_t.get_response_flag.
|
||||
*/
|
||||
static bool get_response_flag(private_ike_header_t *this)
|
||||
{
|
||||
return this->flags.response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ike_header_t.set_response_flag.
|
||||
*/
|
||||
static void set_response_flag(private_ike_header_t *this, bool response)
|
||||
{
|
||||
this->flags.response = response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ike_header_t.get_version_flag.
|
||||
*/
|
||||
static bool get_version_flag(private_ike_header_t *this)
|
||||
{
|
||||
return this->flags.version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ike_header_t.get_initiator_flag.
|
||||
*/
|
||||
static bool get_initiator_flag(private_ike_header_t *this)
|
||||
{
|
||||
return this->flags.initiator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ike_header_t.set_initiator_flag.
|
||||
*/
|
||||
static void set_initiator_flag(private_ike_header_t *this, bool initiator)
|
||||
{
|
||||
this->flags.initiator = initiator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ike_header_t.get_exchange_type.
|
||||
*/
|
||||
static u_int8_t get_exchange_type(private_ike_header_t *this)
|
||||
{
|
||||
return this->exchange_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ike_header_t.set_exchange_type.
|
||||
*/
|
||||
static void set_exchange_type(private_ike_header_t *this, u_int8_t exchange_type)
|
||||
{
|
||||
this->exchange_type = exchange_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements ike_header_t's get_message_id function.
|
||||
* See #ike_header_t.get_message_id for description.
|
||||
*/
|
||||
static u_int32_t get_message_id(private_ike_header_t *this)
|
||||
{
|
||||
return this->message_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ike_header_t.set_message_id.
|
||||
*/
|
||||
static void set_message_id(private_ike_header_t *this, u_int32_t message_id)
|
||||
{
|
||||
this->message_id = message_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ike_header_t.destroy and payload_t.destroy.
|
||||
*/
|
||||
static void destroy(ike_header_t *this)
|
||||
{
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_encoding_rules.
|
||||
*/
|
||||
static void get_encoding_rules(payload_t *this, encoding_rule_t **rules, size_t *rule_count)
|
||||
{
|
||||
*rules = ike_header_encodings;
|
||||
*rule_count = sizeof(ike_header_encodings) / sizeof(encoding_rule_t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_type.
|
||||
*/
|
||||
static payload_type_t get_type(payload_t *this)
|
||||
{
|
||||
return HEADER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_next_type.
|
||||
*/
|
||||
static payload_type_t get_next_type(payload_t *this)
|
||||
{
|
||||
return (((private_ike_header_t*)this)->next_payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_length.
|
||||
*/
|
||||
static size_t get_length(payload_t *this)
|
||||
{
|
||||
return (((private_ike_header_t*)this)->length);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
ike_header_t *ike_header_create()
|
||||
{
|
||||
private_ike_header_t *this = malloc_thing(private_ike_header_t);
|
||||
|
||||
this->public.payload_interface.verify = (status_t (*) (payload_t *))verify;
|
||||
this->public.payload_interface.get_encoding_rules = get_encoding_rules;
|
||||
this->public.payload_interface.get_length = get_length;
|
||||
this->public.payload_interface.get_next_type = get_next_type;
|
||||
this->public.payload_interface.set_next_type = set_next_type;
|
||||
this->public.payload_interface.get_type = get_type;
|
||||
this->public.payload_interface.destroy = (void (*) (payload_t *))destroy;
|
||||
this->public.destroy = destroy;
|
||||
|
||||
this->public.get_initiator_spi = (u_int64_t (*) (ike_header_t*))get_initiator_spi;
|
||||
this->public.set_initiator_spi = (void (*) (ike_header_t*,u_int64_t))set_initiator_spi;
|
||||
this->public.get_responder_spi = (u_int64_t (*) (ike_header_t*))get_responder_spi;
|
||||
this->public.set_responder_spi = (void (*) (ike_header_t *,u_int64_t))set_responder_spi;
|
||||
this->public.get_maj_version = (u_int8_t (*) (ike_header_t*))get_maj_version;
|
||||
this->public.get_min_version = (u_int8_t (*) (ike_header_t*))get_min_version;
|
||||
this->public.get_response_flag = (bool (*) (ike_header_t*))get_response_flag;
|
||||
this->public.set_response_flag = (void (*) (ike_header_t*,bool))set_response_flag;
|
||||
this->public.get_version_flag = (bool (*) (ike_header_t*))get_version_flag;
|
||||
this->public.get_initiator_flag = (bool (*) (ike_header_t*))get_initiator_flag;
|
||||
this->public.set_initiator_flag = (void (*) (ike_header_t*,bool))set_initiator_flag;
|
||||
this->public.get_exchange_type = (u_int8_t (*) (ike_header_t*))get_exchange_type;
|
||||
this->public.set_exchange_type = (void (*) (ike_header_t*,u_int8_t))set_exchange_type;
|
||||
this->public.get_message_id = (u_int32_t (*) (ike_header_t*))get_message_id;
|
||||
this->public.set_message_id = (void (*) (ike_header_t*,u_int32_t))set_message_id;
|
||||
|
||||
/* set default values of the fields */
|
||||
this->initiator_spi = 0;
|
||||
this->responder_spi = 0;
|
||||
this->next_payload = 0;
|
||||
this->maj_version = IKE_MAJOR_VERSION;
|
||||
this->min_version = IKE_MINOR_VERSION;
|
||||
this->exchange_type = EXCHANGE_TYPE_UNDEFINED;
|
||||
this->flags.initiator = TRUE;
|
||||
this->flags.version = HIGHER_VERSION_SUPPORTED_FLAG;
|
||||
this->flags.response = FALSE;
|
||||
this->message_id = 0;
|
||||
this->length = IKE_HEADER_LENGTH;
|
||||
|
||||
return (ike_header_t*)this;
|
||||
}
|
||||
@@ -0,0 +1,261 @@
|
||||
/**
|
||||
* @file ike_header.h
|
||||
*
|
||||
* @brief Interface of ike_header_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef IKE_HEADER_H_
|
||||
#define IKE_HEADER_H_
|
||||
|
||||
#include <types.h>
|
||||
#include <encoding/payloads/payload.h>
|
||||
|
||||
/**
|
||||
* Major Version of IKEv2.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
#define IKE_MAJOR_VERSION 2
|
||||
|
||||
/**
|
||||
* Minor Version of IKEv2.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
#define IKE_MINOR_VERSION 0
|
||||
|
||||
/**
|
||||
* Flag in IKEv2-Header. Always 0.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
#define HIGHER_VERSION_SUPPORTED_FLAG 0
|
||||
|
||||
/**
|
||||
* Length of IKE Header in Bytes.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
#define IKE_HEADER_LENGTH 28
|
||||
|
||||
typedef enum exchange_type_t exchange_type_t;
|
||||
|
||||
/**
|
||||
* @brief Different types of IKE-Exchanges.
|
||||
*
|
||||
* See Draft for different types.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
enum exchange_type_t{
|
||||
|
||||
/**
|
||||
* EXCHANGE_TYPE_UNDEFINED. In private space, since not a official message type.
|
||||
*/
|
||||
EXCHANGE_TYPE_UNDEFINED = 240,
|
||||
|
||||
/**
|
||||
* IKE_SA_INIT.
|
||||
*/
|
||||
IKE_SA_INIT = 34,
|
||||
|
||||
/**
|
||||
* IKE_AUTH.
|
||||
*/
|
||||
IKE_AUTH = 35,
|
||||
|
||||
/**
|
||||
* CREATE_CHILD_SA.
|
||||
*/
|
||||
CREATE_CHILD_SA = 36,
|
||||
|
||||
/**
|
||||
* INFORMATIONAL.
|
||||
*/
|
||||
INFORMATIONAL = 37
|
||||
};
|
||||
|
||||
/**
|
||||
* string mappings for exchange_type_t
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
extern mapping_t exchange_type_m[];
|
||||
|
||||
|
||||
typedef struct ike_header_t ike_header_t;
|
||||
|
||||
/**
|
||||
* @brief An object of this type represents an IKEv2 header and is used to
|
||||
* generate and parse IKEv2 headers.
|
||||
*
|
||||
* The header format of an IKEv2-Message is compatible to the
|
||||
* ISAKMP-Header format to allow implementations supporting
|
||||
* both versions of the IKE-protocol.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - ike_header_create()
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
struct ike_header_t {
|
||||
/**
|
||||
* The payload_t interface.
|
||||
*/
|
||||
payload_t payload_interface;
|
||||
|
||||
/**
|
||||
* @brief Get the initiator spi.
|
||||
*
|
||||
* @param this ike_header_t object
|
||||
* @return initiator_spi
|
||||
*/
|
||||
u_int64_t (*get_initiator_spi) (ike_header_t *this);
|
||||
|
||||
/**
|
||||
* @brief Set the initiator spi.
|
||||
*
|
||||
* @param this ike_header_t object
|
||||
* @param initiator_spi initiator_spi
|
||||
*/
|
||||
void (*set_initiator_spi) (ike_header_t *this, u_int64_t initiator_spi);
|
||||
|
||||
/**
|
||||
* @brief Get the responder spi.
|
||||
*
|
||||
* @param this ike_header_t object
|
||||
* @return responder_spi
|
||||
*/
|
||||
u_int64_t (*get_responder_spi) (ike_header_t *this);
|
||||
|
||||
/**
|
||||
* @brief Set the responder spi.
|
||||
*
|
||||
* @param this ike_header_t object
|
||||
* @param responder_spi responder_spi
|
||||
*/
|
||||
void (*set_responder_spi) (ike_header_t *this, u_int64_t responder_spi);
|
||||
|
||||
/**
|
||||
* @brief Get the major version.
|
||||
*
|
||||
* @param this ike_header_t object
|
||||
* @return major version
|
||||
*/
|
||||
u_int8_t (*get_maj_version) (ike_header_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get the minor version.
|
||||
*
|
||||
* @param this ike_header_t object
|
||||
* @return minor version
|
||||
*/
|
||||
u_int8_t (*get_min_version) (ike_header_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get the response flag.
|
||||
*
|
||||
* @param this ike_header_t object
|
||||
* @return response flag
|
||||
*/
|
||||
bool (*get_response_flag) (ike_header_t *this);
|
||||
|
||||
/**
|
||||
* @brief Set the response flag-
|
||||
*
|
||||
* @param this ike_header_t object
|
||||
* @param response response flag
|
||||
*
|
||||
*/
|
||||
void (*set_response_flag) (ike_header_t *this, bool response);
|
||||
/**
|
||||
* @brief Get "higher version supported"-flag.
|
||||
*
|
||||
* @param this ike_header_t object
|
||||
* @return version flag
|
||||
*/
|
||||
bool (*get_version_flag) (ike_header_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get the initiator flag.
|
||||
*
|
||||
* @param this ike_header_t object
|
||||
* @return initiator flag
|
||||
*/
|
||||
bool (*get_initiator_flag) (ike_header_t *this);
|
||||
|
||||
/**
|
||||
* @brief Set the initiator flag.
|
||||
*
|
||||
* @param this ike_header_t object
|
||||
* @param initiator initiator flag
|
||||
*
|
||||
*/
|
||||
void (*set_initiator_flag) (ike_header_t *this, bool initiator);
|
||||
|
||||
/**
|
||||
* @brief Get the exchange type.
|
||||
*
|
||||
* @param this ike_header_t object
|
||||
* @return exchange type
|
||||
*/
|
||||
u_int8_t (*get_exchange_type) (ike_header_t *this);
|
||||
|
||||
/**
|
||||
* @brief Set the exchange type.
|
||||
*
|
||||
* @param this ike_header_t object
|
||||
* @param exchange_type exchange type
|
||||
*/
|
||||
void (*set_exchange_type) (ike_header_t *this, u_int8_t exchange_type);
|
||||
|
||||
/**
|
||||
* @brief Get the message id.
|
||||
*
|
||||
* @param this ike_header_t object
|
||||
* @return message id
|
||||
*/
|
||||
u_int32_t (*get_message_id) (ike_header_t *this);
|
||||
|
||||
/**
|
||||
* @brief Set the message id.
|
||||
*
|
||||
* @param this ike_header_t object
|
||||
* @param initiator_spi message id
|
||||
*/
|
||||
void (*set_message_id) (ike_header_t *this, u_int32_t message_id);
|
||||
|
||||
/**
|
||||
* @brief Destroys a ike_header_t object.
|
||||
*
|
||||
* @param this ike_header_t object to destroy
|
||||
*/
|
||||
void (*destroy) (ike_header_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Create an ike_header_t object
|
||||
*
|
||||
* @return ike_header_t object
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
ike_header_t *ike_header_create();
|
||||
|
||||
#endif /*IKE_HEADER_H_*/
|
||||
@@ -0,0 +1,276 @@
|
||||
/**
|
||||
* @file ke_payload.c
|
||||
*
|
||||
* @brief Implementation of ke_payload_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "ke_payload.h"
|
||||
|
||||
#include <encoding/payloads/encodings.h>
|
||||
|
||||
|
||||
typedef struct private_ke_payload_t private_ke_payload_t;
|
||||
|
||||
/**
|
||||
* Private data of an ke_payload_t object.
|
||||
*
|
||||
*/
|
||||
struct private_ke_payload_t {
|
||||
/**
|
||||
* Public ke_payload_t interface.
|
||||
*/
|
||||
ke_payload_t public;
|
||||
|
||||
/**
|
||||
* Next payload type.
|
||||
*/
|
||||
u_int8_t next_payload;
|
||||
|
||||
/**
|
||||
* Critical flag.
|
||||
*/
|
||||
bool critical;
|
||||
|
||||
/**
|
||||
* Length of this payload.
|
||||
*/
|
||||
u_int16_t payload_length;
|
||||
|
||||
/**
|
||||
* DH Group Number.
|
||||
*/
|
||||
diffie_hellman_group_t dh_group_number;
|
||||
|
||||
/**
|
||||
* Key Exchange Data of this KE payload.
|
||||
*/
|
||||
chunk_t key_exchange_data;
|
||||
|
||||
/**
|
||||
* @brief Computes the length of this payload.
|
||||
*
|
||||
* @param this calling private_ke_payload_t object
|
||||
*/
|
||||
void (*compute_length) (private_ke_payload_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Encoding rules to parse or generate a IKEv2-KE Payload.
|
||||
*
|
||||
* The defined offsets are the positions in a object of type
|
||||
* private_ke_payload_t.
|
||||
*
|
||||
*/
|
||||
encoding_rule_t ke_payload_encodings[] = {
|
||||
/* 1 Byte next payload type, stored in the field next_payload */
|
||||
{ U_INT_8, offsetof(private_ke_payload_t, next_payload) },
|
||||
/* the critical bit */
|
||||
{ FLAG, offsetof(private_ke_payload_t, critical) },
|
||||
/* 7 Bit reserved bits, nowhere stored */
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
/* Length of the whole payload*/
|
||||
{ PAYLOAD_LENGTH, offsetof(private_ke_payload_t, payload_length) },
|
||||
/* DH Group number as 16 bit field*/
|
||||
{ U_INT_16, offsetof(private_ke_payload_t, dh_group_number) },
|
||||
{ RESERVED_BYTE, 0 },
|
||||
{ RESERVED_BYTE, 0 },
|
||||
/* Key Exchange Data is from variable size */
|
||||
{ KEY_EXCHANGE_DATA, offsetof(private_ke_payload_t, key_exchange_data)}
|
||||
};
|
||||
|
||||
/*
|
||||
1 2 3
|
||||
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 !C! RESERVED ! Payload Length !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! DH Group # ! RESERVED !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! !
|
||||
~ Key Exchange Data ~
|
||||
! !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.verify.
|
||||
*/
|
||||
static status_t verify(private_ke_payload_t *this)
|
||||
{
|
||||
/* dh group is not verified in here */
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.destroy.
|
||||
*/
|
||||
static void destroy(private_ke_payload_t *this)
|
||||
{
|
||||
if (this->key_exchange_data.ptr != NULL)
|
||||
{
|
||||
free(this->key_exchange_data.ptr);
|
||||
}
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_encoding_rules.
|
||||
*/
|
||||
static void get_encoding_rules(private_ke_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
|
||||
{
|
||||
*rules = ke_payload_encodings;
|
||||
*rule_count = sizeof(ke_payload_encodings) / sizeof(encoding_rule_t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_type.
|
||||
*/
|
||||
static payload_type_t get_type(private_ke_payload_t *this)
|
||||
{
|
||||
return KEY_EXCHANGE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_next_type.
|
||||
*/
|
||||
static payload_type_t get_next_type(private_ke_payload_t *this)
|
||||
{
|
||||
return (this->next_payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.set_next_type.
|
||||
*/
|
||||
static void set_next_type(private_ke_payload_t *this,payload_type_t type)
|
||||
{
|
||||
this->next_payload = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_length.
|
||||
*/
|
||||
static size_t get_length(private_ke_payload_t *this)
|
||||
{
|
||||
this->compute_length(this);
|
||||
return this->payload_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of private_ke_payload_t.compute_length.
|
||||
*/
|
||||
static void compute_length (private_ke_payload_t *this)
|
||||
{
|
||||
size_t length = KE_PAYLOAD_HEADER_LENGTH;
|
||||
if (this->key_exchange_data.ptr != NULL)
|
||||
{
|
||||
length += this->key_exchange_data.len;
|
||||
}
|
||||
this->payload_length = length;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of ke_payload_t.get_key_exchange_data.
|
||||
*/
|
||||
static chunk_t get_key_exchange_data(private_ke_payload_t *this)
|
||||
{
|
||||
return (this->key_exchange_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ke_payload_t.set_key_exchange_data.
|
||||
*/
|
||||
static void set_key_exchange_data(private_ke_payload_t *this, chunk_t key_exchange_data)
|
||||
{
|
||||
/* destroy existing data first */
|
||||
if (this->key_exchange_data.ptr != NULL)
|
||||
{
|
||||
/* free existing value */
|
||||
free(this->key_exchange_data.ptr);
|
||||
this->key_exchange_data.ptr = NULL;
|
||||
this->key_exchange_data.len = 0;
|
||||
|
||||
}
|
||||
|
||||
this->key_exchange_data.ptr = clalloc(key_exchange_data.ptr,key_exchange_data.len);
|
||||
|
||||
this->key_exchange_data.len = key_exchange_data.len;
|
||||
this->compute_length(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ke_payload_t.get_dh_group_number.
|
||||
*/
|
||||
static diffie_hellman_group_t get_dh_group_number(private_ke_payload_t *this)
|
||||
{
|
||||
return this->dh_group_number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ke_payload_t.set_dh_group_number.
|
||||
*/
|
||||
static void set_dh_group_number(private_ke_payload_t *this, diffie_hellman_group_t dh_group_number)
|
||||
{
|
||||
this->dh_group_number = dh_group_number;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
ke_payload_t *ke_payload_create()
|
||||
{
|
||||
private_ke_payload_t *this = malloc_thing(private_ke_payload_t);
|
||||
|
||||
/* interface functions */
|
||||
this->public.payload_interface.verify = (status_t (*) (payload_t *))verify;
|
||||
this->public.payload_interface.get_encoding_rules = (void (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules;
|
||||
this->public.payload_interface.get_length = (size_t (*) (payload_t *)) get_length;
|
||||
this->public.payload_interface.get_next_type = (payload_type_t (*) (payload_t *)) get_next_type;
|
||||
this->public.payload_interface.set_next_type = (void (*) (payload_t *,payload_type_t)) set_next_type;
|
||||
this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_type;
|
||||
this->public.payload_interface.destroy = (void (*) (payload_t *))destroy;
|
||||
|
||||
/* public functions */
|
||||
this->public.get_key_exchange_data = (chunk_t (*) (ke_payload_t *)) get_key_exchange_data;
|
||||
this->public.set_key_exchange_data = (void (*) (ke_payload_t *,chunk_t)) set_key_exchange_data;
|
||||
this->public.get_dh_group_number = (diffie_hellman_group_t (*) (ke_payload_t *)) get_dh_group_number;
|
||||
this->public.set_dh_group_number =(void (*) (ke_payload_t *,diffie_hellman_group_t)) set_dh_group_number;
|
||||
this->public.destroy = (void (*) (ke_payload_t *)) destroy;
|
||||
|
||||
/* private functions */
|
||||
this->compute_length = compute_length;
|
||||
|
||||
/* set default values of the fields */
|
||||
this->critical = FALSE;
|
||||
this->next_payload = NO_PAYLOAD;
|
||||
this->payload_length = KE_PAYLOAD_HEADER_LENGTH;
|
||||
this->key_exchange_data.ptr = NULL;
|
||||
this->key_exchange_data.len = 0;
|
||||
this->dh_group_number = 0;
|
||||
|
||||
return (&(this->public));
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/**
|
||||
* @file ke_payload.h
|
||||
*
|
||||
* @brief Interface of ke_payload_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef KE_PAYLOAD_H_
|
||||
#define KE_PAYLOAD_H_
|
||||
|
||||
#include <types.h>
|
||||
#include <encoding/payloads/payload.h>
|
||||
#include <encoding/payloads/transform_substructure.h>
|
||||
#include <utils/linked_list.h>
|
||||
/**
|
||||
* KE payload length in bytes without any key exchange data.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
#define KE_PAYLOAD_HEADER_LENGTH 8
|
||||
|
||||
|
||||
typedef struct ke_payload_t ke_payload_t;
|
||||
|
||||
/**
|
||||
* @brief Class representing an IKEv2-KE Payload.
|
||||
*
|
||||
* The KE Payload format is described in RFC section 3.4.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - ke_payload_create()
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
struct ke_payload_t {
|
||||
/**
|
||||
* The payload_t interface.
|
||||
*/
|
||||
payload_t payload_interface;
|
||||
|
||||
/**
|
||||
* @brief Returns the currently set key exchange data of this KE payload.
|
||||
*
|
||||
* @warning Returned data are not copied.
|
||||
*
|
||||
* @param this calling ke_payload_t object
|
||||
* @return chunk_t pointing to the value
|
||||
*/
|
||||
chunk_t (*get_key_exchange_data) (ke_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Sets the key exchange data of this KE payload.
|
||||
*
|
||||
* @warning Value is getting copied.
|
||||
*
|
||||
* @param this calling ke_payload_t object
|
||||
* @param key_exchange_data chunk_t pointing to the value to set
|
||||
*/
|
||||
void (*set_key_exchange_data) (ke_payload_t *this, chunk_t key_exchange_data);
|
||||
|
||||
/**
|
||||
* @brief Gets the Diffie-Hellman Group Number of this KE payload.
|
||||
*
|
||||
* @param this calling ke_payload_t object
|
||||
* @return DH Group Number of this payload
|
||||
*/
|
||||
diffie_hellman_group_t (*get_dh_group_number) (ke_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Sets the Diffie-Hellman Group Number of this KE payload.
|
||||
*
|
||||
* @param this calling ke_payload_t object
|
||||
* @param dh_group_number DH Group to set
|
||||
*/
|
||||
void (*set_dh_group_number) (ke_payload_t *this, diffie_hellman_group_t dh_group_number);
|
||||
|
||||
/**
|
||||
* @brief Destroys an ke_payload_t object.
|
||||
*
|
||||
* @param this ke_payload_t object to destroy
|
||||
*/
|
||||
void (*destroy) (ke_payload_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Creates an empty ke_payload_t object
|
||||
*
|
||||
* @return ke_payload_t object
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
ke_payload_t *ke_payload_create();
|
||||
|
||||
|
||||
#endif /*KE_PAYLOAD_H_*/
|
||||
@@ -0,0 +1,241 @@
|
||||
/**
|
||||
* @file nonce_payload.h
|
||||
*
|
||||
* @brief Implementation of nonce_payload_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/* offsetof macro */
|
||||
#include <stddef.h>
|
||||
|
||||
#include "nonce_payload.h"
|
||||
|
||||
#include <encoding/payloads/encodings.h>
|
||||
|
||||
|
||||
typedef struct private_nonce_payload_t private_nonce_payload_t;
|
||||
|
||||
/**
|
||||
* Private data of an nonce_payload_t object.
|
||||
*
|
||||
*/
|
||||
struct private_nonce_payload_t {
|
||||
/**
|
||||
* Public nonce_payload_t interface.
|
||||
*/
|
||||
nonce_payload_t public;
|
||||
|
||||
/**
|
||||
* Next payload type.
|
||||
*/
|
||||
u_int8_t next_payload;
|
||||
|
||||
/**
|
||||
* Critical flag.
|
||||
*/
|
||||
bool critical;
|
||||
|
||||
/**
|
||||
* Length of this payload.
|
||||
*/
|
||||
u_int16_t payload_length;
|
||||
|
||||
/**
|
||||
* The contained nonce value.
|
||||
*/
|
||||
chunk_t nonce;
|
||||
|
||||
/**
|
||||
* @brief Computes the length of this payload.
|
||||
*
|
||||
* @param this calling private_nonce_payload_t object
|
||||
*/
|
||||
void (*compute_length) (private_nonce_payload_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Encoding rules to parse or generate a nonce payload
|
||||
*
|
||||
* The defined offsets are the positions in a object of type
|
||||
* private_nonce_payload_t.
|
||||
*
|
||||
*/
|
||||
encoding_rule_t nonce_payload_encodings[] = {
|
||||
/* 1 Byte next payload type, stored in the field next_payload */
|
||||
{ U_INT_8, offsetof(private_nonce_payload_t, next_payload) },
|
||||
/* the critical bit */
|
||||
{ FLAG, offsetof(private_nonce_payload_t, critical) },
|
||||
/* 7 Bit reserved bits, nowhere stored */
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
/* Length of the whole nonce payload*/
|
||||
{ PAYLOAD_LENGTH, offsetof(private_nonce_payload_t, payload_length) },
|
||||
/* some nonce bytes, lenth is defined in PAYLOAD_LENGTH */
|
||||
{ NONCE_DATA, offsetof(private_nonce_payload_t, nonce) }
|
||||
};
|
||||
|
||||
/* 1 2 3
|
||||
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 !C! RESERVED ! Payload Length !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! !
|
||||
~ Nonce Data ~
|
||||
! !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.verify.
|
||||
*/
|
||||
static status_t verify(private_nonce_payload_t *this)
|
||||
{
|
||||
if ((this->nonce.len < 16) || ((this->nonce.len > 256)))
|
||||
{
|
||||
/* nonce length is wrong */
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of nonce_payload_t.set_nonce.
|
||||
*/
|
||||
static status_t set_nonce(private_nonce_payload_t *this, chunk_t nonce)
|
||||
{
|
||||
this->nonce.ptr = clalloc(nonce.ptr, nonce.len);
|
||||
this->nonce.len = nonce.len;
|
||||
this->payload_length = NONCE_PAYLOAD_HEADER_LENGTH + nonce.len;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of nonce_payload_t.get_nonce.
|
||||
*/
|
||||
static chunk_t get_nonce(private_nonce_payload_t *this)
|
||||
{
|
||||
chunk_t nonce;
|
||||
nonce.ptr = clalloc(this->nonce.ptr,this->nonce.len);
|
||||
nonce.len = this->nonce.len;
|
||||
return nonce;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of nonce_payload_t.get_encoding_rules.
|
||||
*/
|
||||
static void get_encoding_rules(private_nonce_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
|
||||
{
|
||||
*rules = nonce_payload_encodings;
|
||||
*rule_count = sizeof(nonce_payload_encodings) / sizeof(encoding_rule_t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_type.
|
||||
*/
|
||||
static payload_type_t get_type(private_nonce_payload_t *this)
|
||||
{
|
||||
return NONCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_next_type.
|
||||
*/
|
||||
static payload_type_t get_next_type(private_nonce_payload_t *this)
|
||||
{
|
||||
return (this->next_payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.set_next_type.
|
||||
*/
|
||||
static void set_next_type(private_nonce_payload_t *this,payload_type_t type)
|
||||
{
|
||||
this->next_payload = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_length.
|
||||
*/
|
||||
static size_t get_length(private_nonce_payload_t *this)
|
||||
{
|
||||
this->compute_length(this);
|
||||
return this->payload_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of private_id_payload_t.compute_length.
|
||||
*/
|
||||
static void compute_length(private_nonce_payload_t *this)
|
||||
{
|
||||
this->payload_length = NONCE_PAYLOAD_HEADER_LENGTH + this->nonce.len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.destroy and nonce_payload_t.destroy.
|
||||
*/
|
||||
static void destroy(private_nonce_payload_t *this)
|
||||
{
|
||||
if (this->nonce.ptr != NULL)
|
||||
{
|
||||
free(this->nonce.ptr);
|
||||
}
|
||||
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
nonce_payload_t *nonce_payload_create()
|
||||
{
|
||||
private_nonce_payload_t *this = malloc_thing(private_nonce_payload_t);
|
||||
|
||||
/* interface functions */
|
||||
this->public.payload_interface.verify = (status_t (*) (payload_t *))verify;
|
||||
this->public.payload_interface.get_encoding_rules = (void (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules;
|
||||
this->public.payload_interface.get_length = (size_t (*) (payload_t *)) get_length;
|
||||
this->public.payload_interface.get_next_type = (payload_type_t (*) (payload_t *)) get_next_type;
|
||||
this->public.payload_interface.set_next_type = (void (*) (payload_t *,payload_type_t)) set_next_type;
|
||||
this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_type;
|
||||
this->public.payload_interface.destroy = (void (*) (payload_t *))destroy;
|
||||
|
||||
/* public functions */
|
||||
this->public.destroy = (void (*) (nonce_payload_t *)) destroy;
|
||||
this->public.set_nonce = (void (*) (nonce_payload_t *,chunk_t)) set_nonce;
|
||||
this->public.get_nonce = (chunk_t (*) (nonce_payload_t *)) get_nonce;
|
||||
|
||||
/* private functions */
|
||||
this->compute_length = compute_length;
|
||||
|
||||
/* private variables */
|
||||
this->critical = FALSE;
|
||||
this->next_payload = NO_PAYLOAD;
|
||||
this->payload_length = NONCE_PAYLOAD_HEADER_LENGTH;
|
||||
this->nonce.ptr = NULL;
|
||||
this->nonce.len = 0;
|
||||
|
||||
return (&(this->public));
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
* @file nonce_payload.h
|
||||
*
|
||||
* @brief Interface of nonce_payload_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef NONCE_PAYLOAD_H_
|
||||
#define NONCE_PAYLOAD_H_
|
||||
|
||||
#include <types.h>
|
||||
#include <encoding/payloads/payload.h>
|
||||
|
||||
/**
|
||||
* Length of a nonce payload without a nonce in bytes.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
#define NONCE_PAYLOAD_HEADER_LENGTH 4
|
||||
|
||||
typedef struct nonce_payload_t nonce_payload_t;
|
||||
|
||||
/**
|
||||
* Object representing an IKEv2 Nonce payload.
|
||||
*
|
||||
* The Nonce payload format is described in RFC section 3.3.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - nonce_payload_create()
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
struct nonce_payload_t {
|
||||
/**
|
||||
* The payload_t interface.
|
||||
*/
|
||||
payload_t payload_interface;
|
||||
|
||||
/**
|
||||
* @brief Set the nonce value.
|
||||
*
|
||||
* @param this calling nonce_payload_t object
|
||||
* @param nonce chunk containing the nonce, will be cloned
|
||||
*/
|
||||
void (*set_nonce) (nonce_payload_t *this, chunk_t nonce);
|
||||
|
||||
/**
|
||||
* @brief Get the nonce value.
|
||||
*
|
||||
* @param this calling nonce_payload_t object
|
||||
* @return a chunk containing the cloned nonce
|
||||
*/
|
||||
chunk_t (*get_nonce) (nonce_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Destroys an nonce_payload_t object.
|
||||
*
|
||||
* @param this nonce_payload_t object to destroy
|
||||
*/
|
||||
void (*destroy) (nonce_payload_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Creates an empty nonce_payload_t object
|
||||
*
|
||||
* @return nonce_payload_t object
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
|
||||
nonce_payload_t *nonce_payload_create();
|
||||
|
||||
|
||||
#endif /*NONCE_PAYLOAD_H_*/
|
||||
@@ -0,0 +1,441 @@
|
||||
/**
|
||||
* @file notify_payload.c
|
||||
*
|
||||
* @brief Implementation of notify_payload_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "notify_payload.h"
|
||||
|
||||
#include <daemon.h>
|
||||
#include <encoding/payloads/encodings.h>
|
||||
|
||||
/**
|
||||
* String mappings for notify_message_type_t.
|
||||
*/
|
||||
mapping_t notify_message_type_m[] = {
|
||||
{UNSUPPORTED_CRITICAL_PAYLOAD, "UNSUPPORTED_CRITICAL_PAYLOAD"},
|
||||
{INVALID_IKE_SPI, "INVALID_IKE_SPI"},
|
||||
{INVALID_MAJOR_VERSION, "INVALID_MAJOR_VERSION"},
|
||||
{INVALID_SYNTAX, "INVALID_SYNTAX"},
|
||||
{INVALID_MESSAGE_ID, "INVALID_MESSAGE_ID"},
|
||||
{INVALID_SPI, "INVALID_SPI"},
|
||||
{NO_PROPOSAL_CHOSEN, "NO_PROPOSAL_CHOSEN"},
|
||||
{INVALID_KE_PAYLOAD, "INVALID_KE_PAYLOAD"},
|
||||
{AUTHENTICATION_FAILED, "AUTHENTICATION_FAILED"},
|
||||
{SINGLE_PAIR_REQUIRED, "SINGLE_PAIR_REQUIRED"},
|
||||
{NO_ADDITIONAL_SAS, "NO_ADDITIONAL_SAS"},
|
||||
{INTERNAL_ADDRESS_FAILURE, "INTERNAL_ADDRESS_FAILURE"},
|
||||
{FAILED_CP_REQUIRED, "FAILED_CP_REQUIRED"},
|
||||
{TS_UACCEPTABLE, "TS_UACCEPTABLE"},
|
||||
{INVALID_SELECTORS, "INVALID_SELECTORS"},
|
||||
{INITIAL_CONTACT, "INITIAL_CONTACT"},
|
||||
{SET_WINDOW_SIZE, "SET_WINDOW_SIZE"},
|
||||
{MAPPING_END, NULL}
|
||||
};
|
||||
|
||||
typedef struct private_notify_payload_t private_notify_payload_t;
|
||||
|
||||
/**
|
||||
* Private data of an notify_payload_t object.
|
||||
*
|
||||
*/
|
||||
struct private_notify_payload_t {
|
||||
/**
|
||||
* Public notify_payload_t interface.
|
||||
*/
|
||||
notify_payload_t public;
|
||||
|
||||
/**
|
||||
* Next payload type.
|
||||
*/
|
||||
u_int8_t next_payload;
|
||||
|
||||
/**
|
||||
* Critical flag.
|
||||
*/
|
||||
bool critical;
|
||||
|
||||
/**
|
||||
* Length of this payload.
|
||||
*/
|
||||
u_int16_t payload_length;
|
||||
|
||||
/**
|
||||
* Protocol id.
|
||||
*/
|
||||
u_int8_t protocol_id;
|
||||
|
||||
/**
|
||||
* Spi size.
|
||||
*/
|
||||
u_int8_t spi_size;
|
||||
|
||||
/**
|
||||
* Notify message type.
|
||||
*/
|
||||
u_int16_t notify_message_type;
|
||||
|
||||
/**
|
||||
* Security parameter index (spi).
|
||||
*/
|
||||
chunk_t spi;
|
||||
|
||||
/**
|
||||
* Notification data.
|
||||
*/
|
||||
chunk_t notification_data;
|
||||
|
||||
/**
|
||||
* Assigned logger
|
||||
*/
|
||||
logger_t *logger;
|
||||
|
||||
/**
|
||||
* @brief Computes the length of this payload.
|
||||
*
|
||||
* @param this calling private_ke_payload_t object
|
||||
*/
|
||||
void (*compute_length) (private_notify_payload_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Encoding rules to parse or generate a IKEv2-Notify Payload.
|
||||
*
|
||||
* The defined offsets are the positions in a object of type
|
||||
* private_notify_payload_t.
|
||||
*
|
||||
*/
|
||||
encoding_rule_t notify_payload_encodings[] = {
|
||||
/* 1 Byte next payload type, stored in the field next_payload */
|
||||
{ U_INT_8, offsetof(private_notify_payload_t, next_payload) },
|
||||
/* the critical bit */
|
||||
{ FLAG, offsetof(private_notify_payload_t, critical) },
|
||||
/* 7 Bit reserved bits, nowhere stored */
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
/* Length of the whole payload*/
|
||||
{ PAYLOAD_LENGTH, offsetof(private_notify_payload_t, payload_length) },
|
||||
/* Protocol ID as 8 bit field*/
|
||||
{ U_INT_8, offsetof(private_notify_payload_t, protocol_id) },
|
||||
/* SPI Size as 8 bit field*/
|
||||
{ SPI_SIZE, offsetof(private_notify_payload_t, spi_size) },
|
||||
/* Notify message type as 16 bit field*/
|
||||
{ U_INT_16, offsetof(private_notify_payload_t, notify_message_type) },
|
||||
/* SPI as variable length field*/
|
||||
{ SPI, offsetof(private_notify_payload_t, spi) },
|
||||
/* Key Exchange Data is from variable size */
|
||||
{ NOTIFICATION_DATA, offsetof(private_notify_payload_t, notification_data) }
|
||||
};
|
||||
|
||||
/*
|
||||
1 2 3
|
||||
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 !C! RESERVED ! Payload Length !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! Protocol ID ! SPI Size ! Notify Message Type !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! !
|
||||
~ Security Parameter Index (SPI) ~
|
||||
! !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! !
|
||||
~ Notification Data ~
|
||||
! !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.verify.
|
||||
*/
|
||||
static status_t verify(private_notify_payload_t *this)
|
||||
{
|
||||
if (this->protocol_id > 3)
|
||||
{
|
||||
/* reserved for future use */
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
/* TODO: Check all kinds of notify */
|
||||
|
||||
if (this->notify_message_type == INVALID_KE_PAYLOAD)
|
||||
{
|
||||
/* check notification data */
|
||||
diffie_hellman_group_t dh_group;
|
||||
if (this->notification_data.len != 2)
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
dh_group = ntohs(*((u_int16_t*)this->notification_data.ptr));
|
||||
switch (dh_group)
|
||||
{
|
||||
case MODP_768_BIT:
|
||||
case MODP_1024_BIT:
|
||||
case MODP_1536_BIT:
|
||||
case MODP_2048_BIT:
|
||||
case MODP_3072_BIT:
|
||||
case MODP_4096_BIT:
|
||||
case MODP_6144_BIT:
|
||||
case MODP_8192_BIT:
|
||||
break;
|
||||
default:
|
||||
this->logger->log(this->logger, ERROR, "Bad DH group (%d)", dh_group);
|
||||
return FAILED;
|
||||
}
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_encoding_rules.
|
||||
*/
|
||||
static void get_encoding_rules(private_notify_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
|
||||
{
|
||||
*rules = notify_payload_encodings;
|
||||
*rule_count = sizeof(notify_payload_encodings) / sizeof(encoding_rule_t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_type.
|
||||
*/
|
||||
static payload_type_t get_type(private_notify_payload_t *this)
|
||||
{
|
||||
return NOTIFY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_next_type.
|
||||
*/
|
||||
static payload_type_t get_next_type(private_notify_payload_t *this)
|
||||
{
|
||||
return (this->next_payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.set_next_type.
|
||||
*/
|
||||
static void set_next_type(private_notify_payload_t *this,payload_type_t type)
|
||||
{
|
||||
this->next_payload = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_length.
|
||||
*/
|
||||
static size_t get_length(private_notify_payload_t *this)
|
||||
{
|
||||
this->compute_length(this);
|
||||
return this->payload_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of private_notify_payload_t.compute_length.
|
||||
*/
|
||||
static void compute_length (private_notify_payload_t *this)
|
||||
{
|
||||
size_t length = NOTIFY_PAYLOAD_HEADER_LENGTH;
|
||||
if (this->notification_data.ptr != NULL)
|
||||
{
|
||||
length += this->notification_data.len;
|
||||
}
|
||||
if (this->spi.ptr != NULL)
|
||||
{
|
||||
length += this->spi.len;
|
||||
}
|
||||
|
||||
this->payload_length = length;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of notify_payload_t.get_protocol_id.
|
||||
*/
|
||||
static u_int8_t get_protocol_id(private_notify_payload_t *this)
|
||||
{
|
||||
return this->protocol_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of notify_payload_t.set_protocol_id.
|
||||
*/
|
||||
static void set_protocol_id(private_notify_payload_t *this, u_int8_t protocol_id)
|
||||
{
|
||||
this->protocol_id = protocol_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of notify_payload_t.get_notify_message_type.
|
||||
*/
|
||||
static u_int16_t get_notify_message_type(private_notify_payload_t *this)
|
||||
{
|
||||
return this->notify_message_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of notify_payload_t.set_notify_message_type.
|
||||
*/
|
||||
static void set_notify_message_type(private_notify_payload_t *this, u_int16_t notify_message_type)
|
||||
{
|
||||
this->notify_message_type = notify_message_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of notify_payload_t.get_spi.
|
||||
*/
|
||||
static chunk_t get_spi(private_notify_payload_t *this)
|
||||
{
|
||||
return (this->spi);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of notify_payload_t.set_spi.
|
||||
*/
|
||||
static void set_spi(private_notify_payload_t *this, chunk_t spi)
|
||||
{
|
||||
/* destroy existing data first */
|
||||
if (this->spi.ptr != NULL)
|
||||
{
|
||||
/* free existing value */
|
||||
free(this->spi.ptr);
|
||||
this->spi.ptr = NULL;
|
||||
this->spi.len = 0;
|
||||
|
||||
}
|
||||
|
||||
this->spi.ptr = clalloc(spi.ptr,spi.len);
|
||||
|
||||
this->spi.len = spi.len;
|
||||
this->spi_size = spi.len;
|
||||
this->compute_length(this);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of notify_payload_t.get_notification_data.
|
||||
*/
|
||||
static chunk_t get_notification_data(private_notify_payload_t *this)
|
||||
{
|
||||
return (this->notification_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of notify_payload_t.set_notification_data.
|
||||
*/
|
||||
static status_t set_notification_data(private_notify_payload_t *this, chunk_t notification_data)
|
||||
{
|
||||
/* destroy existing data first */
|
||||
if (this->notification_data.ptr != NULL)
|
||||
{
|
||||
/* free existing value */
|
||||
free(this->notification_data.ptr);
|
||||
this->notification_data.ptr = NULL;
|
||||
this->notification_data.len = 0;
|
||||
|
||||
}
|
||||
|
||||
this->notification_data.ptr = clalloc(notification_data.ptr,notification_data.len);
|
||||
this->notification_data.len = notification_data.len;
|
||||
this->compute_length(this);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of notify_payload_t.destroy and notify_payload_t.destroy.
|
||||
*/
|
||||
static status_t destroy(private_notify_payload_t *this)
|
||||
{
|
||||
if (this->notification_data.ptr != NULL)
|
||||
{
|
||||
free(this->notification_data.ptr);
|
||||
}
|
||||
if (this->spi.ptr != NULL)
|
||||
{
|
||||
free(this->spi.ptr);
|
||||
}
|
||||
|
||||
free(this);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
notify_payload_t *notify_payload_create()
|
||||
{
|
||||
private_notify_payload_t *this = malloc_thing(private_notify_payload_t);
|
||||
|
||||
/* interface functions */
|
||||
this->public.payload_interface.verify = (status_t (*) (payload_t *))verify;
|
||||
this->public.payload_interface.get_encoding_rules = (void (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules;
|
||||
this->public.payload_interface.get_length = (size_t (*) (payload_t *)) get_length;
|
||||
this->public.payload_interface.get_next_type = (payload_type_t (*) (payload_t *)) get_next_type;
|
||||
this->public.payload_interface.set_next_type = (void (*) (payload_t *,payload_type_t)) set_next_type;
|
||||
this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_type;
|
||||
this->public.payload_interface.destroy = (void (*) (payload_t *))destroy;
|
||||
|
||||
/* public functions */
|
||||
this->public.get_protocol_id = (u_int8_t (*) (notify_payload_t *)) get_protocol_id;
|
||||
this->public.set_protocol_id = (void (*) (notify_payload_t *,u_int8_t)) set_protocol_id;
|
||||
this->public.get_notify_message_type = (u_int16_t (*) (notify_payload_t *)) get_notify_message_type;
|
||||
this->public.set_notify_message_type = (void (*) (notify_payload_t *,u_int16_t)) set_notify_message_type;
|
||||
this->public.get_spi = (chunk_t (*) (notify_payload_t *)) get_spi;
|
||||
this->public.set_spi = (void (*) (notify_payload_t *,chunk_t)) set_spi;
|
||||
this->public.get_notification_data = (chunk_t (*) (notify_payload_t *)) get_notification_data;
|
||||
this->public.set_notification_data = (void (*) (notify_payload_t *,chunk_t)) set_notification_data;
|
||||
this->public.destroy = (void (*) (notify_payload_t *)) destroy;
|
||||
|
||||
/* private functions */
|
||||
this->compute_length = compute_length;
|
||||
|
||||
/* set default values of the fields */
|
||||
this->critical = FALSE;
|
||||
this->next_payload = NO_PAYLOAD;
|
||||
this->payload_length = NOTIFY_PAYLOAD_HEADER_LENGTH;
|
||||
this->protocol_id = 0;
|
||||
this->notify_message_type = 0;
|
||||
this->spi.ptr = NULL;
|
||||
this->spi.len = 0;
|
||||
this->spi_size = 0;
|
||||
this->notification_data.ptr = NULL;
|
||||
this->notification_data.len = 0;
|
||||
this->logger = logger_manager->get_logger(logger_manager, PAYLOAD);
|
||||
|
||||
return (&(this->public));
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
notify_payload_t *notify_payload_create_from_protocol_and_type(protocol_id_t protocol_id, notify_message_type_t notify_message_type)
|
||||
{
|
||||
notify_payload_t *notify = notify_payload_create();
|
||||
|
||||
notify->set_notify_message_type(notify,notify_message_type);
|
||||
notify->set_protocol_id(notify,protocol_id);
|
||||
|
||||
return notify;
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
/**
|
||||
* @file notify_payload.h
|
||||
*
|
||||
* @brief Interface of notify_payload_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef NOTIFY_PAYLOAD_H_
|
||||
#define NOTIFY_PAYLOAD_H_
|
||||
|
||||
#include <types.h>
|
||||
#include <encoding/payloads/payload.h>
|
||||
#include <encoding/payloads/proposal_substructure.h>
|
||||
#include <utils/linked_list.h>
|
||||
|
||||
/**
|
||||
* Notify payload length in bytes without any spi and notification data.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
#define NOTIFY_PAYLOAD_HEADER_LENGTH 8
|
||||
|
||||
typedef enum notify_message_type_t notify_message_type_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Notify message types.
|
||||
*
|
||||
* See IKEv2 RFC 3.10.1.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
enum notify_message_type_t {
|
||||
UNSUPPORTED_CRITICAL_PAYLOAD = 1,
|
||||
INVALID_IKE_SPI = 4,
|
||||
INVALID_MAJOR_VERSION = 5,
|
||||
INVALID_SYNTAX = 7,
|
||||
INVALID_MESSAGE_ID = 9,
|
||||
INVALID_SPI = 11,
|
||||
NO_PROPOSAL_CHOSEN = 14,
|
||||
INVALID_KE_PAYLOAD = 17,
|
||||
AUTHENTICATION_FAILED = 24,
|
||||
SINGLE_PAIR_REQUIRED = 34,
|
||||
NO_ADDITIONAL_SAS = 35,
|
||||
INTERNAL_ADDRESS_FAILURE = 36,
|
||||
FAILED_CP_REQUIRED = 37,
|
||||
TS_UACCEPTABLE = 38,
|
||||
INVALID_SELECTORS = 39,
|
||||
|
||||
INITIAL_CONTACT = 16384,
|
||||
SET_WINDOW_SIZE = 16385
|
||||
};
|
||||
|
||||
/**
|
||||
* String mappings for notify_message_type_t.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
extern mapping_t notify_message_type_m[];
|
||||
|
||||
|
||||
typedef struct notify_payload_t notify_payload_t;
|
||||
|
||||
/**
|
||||
* @brief Class representing an IKEv2-Notify Payload.
|
||||
*
|
||||
* The Notify Payload format is described in Draft section 3.10.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - notify_payload_create()
|
||||
* - notify_payload_create_from_protocol_and_type()
|
||||
*
|
||||
* @todo Build specified constructor/getter for notify's
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
struct notify_payload_t {
|
||||
/**
|
||||
* The payload_t interface.
|
||||
*/
|
||||
payload_t payload_interface;
|
||||
|
||||
/**
|
||||
* @brief Gets the protocol id of this payload.
|
||||
*
|
||||
* @param this calling notify_payload_t object
|
||||
* @return protocol id of this payload
|
||||
*/
|
||||
u_int8_t (*get_protocol_id) (notify_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Sets the protocol id of this payload.
|
||||
*
|
||||
* @param this calling notify_payload_t object
|
||||
* @param protocol_id protocol id to set
|
||||
*/
|
||||
void (*set_protocol_id) (notify_payload_t *this, u_int8_t protocol_id);
|
||||
|
||||
/**
|
||||
* @brief Gets the notify message type of this payload.
|
||||
*
|
||||
* @param this calling notify_payload_t object
|
||||
* @return notify message type of this payload
|
||||
*/
|
||||
u_int16_t (*get_notify_message_type) (notify_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Sets notify message type of this payload.
|
||||
*
|
||||
* @param this calling notify_payload_t object
|
||||
* @param notify_message_type notify message type to set
|
||||
*/
|
||||
void (*set_notify_message_type) (notify_payload_t *this, u_int16_t notify_message_type);
|
||||
|
||||
/**
|
||||
* @brief Returns the currently set spi of this payload.
|
||||
*
|
||||
* @warning Returned data are not copied.
|
||||
*
|
||||
* @param this calling notify_payload_t object
|
||||
* @return chunk_t pointing to the value
|
||||
*/
|
||||
chunk_t (*get_spi) (notify_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Sets the spi of this payload.
|
||||
*
|
||||
* @warning Value is getting copied.
|
||||
*
|
||||
* @param this calling notify_payload_t object
|
||||
* @param spi chunk_t pointing to the value to set
|
||||
*/
|
||||
void (*set_spi) (notify_payload_t *this, chunk_t spi);
|
||||
|
||||
/**
|
||||
* @brief Returns the currently set notification data of payload.
|
||||
*
|
||||
* @warning Returned data are not copied.
|
||||
*
|
||||
* @param this calling notify_payload_t object
|
||||
* @return chunk_t pointing to the value
|
||||
*/
|
||||
chunk_t (*get_notification_data) (notify_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Sets the notification data of this payload.
|
||||
*
|
||||
* @warning Value is getting copied.
|
||||
*
|
||||
* @param this calling notify_payload_t object
|
||||
* @param notification_data chunk_t pointing to the value to set
|
||||
*/
|
||||
void (*set_notification_data) (notify_payload_t *this, chunk_t notification_data);
|
||||
|
||||
/**
|
||||
* @brief Destroys an notify_payload_t object.
|
||||
*
|
||||
* @param this notify_payload_t object to destroy
|
||||
*/
|
||||
void (*destroy) (notify_payload_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Creates an empty notify_payload_t object
|
||||
*
|
||||
* @return created notify_payload_t object
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
notify_payload_t *notify_payload_create();
|
||||
|
||||
/**
|
||||
* @brief Creates an notify_payload_t object of specific type for specific protocol id.
|
||||
*
|
||||
* @param protocol_id protocol id (IKE, AH or ESP)
|
||||
* @param notify_message_type notify type (see notify_message_type_t)
|
||||
* @return notify_payload_t object
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
notify_payload_t *notify_payload_create_from_protocol_and_type(protocol_id_t protocol_id, notify_message_type_t notify_message_type);
|
||||
|
||||
|
||||
#endif /*NOTIFY_PAYLOAD_H_*/
|
||||
@@ -0,0 +1,131 @@
|
||||
/**
|
||||
* @file payload.c
|
||||
*
|
||||
* @brief Generic constructor to the payload_t interface.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
|
||||
#include "payload.h"
|
||||
|
||||
#include <encoding/payloads/ike_header.h>
|
||||
#include <encoding/payloads/sa_payload.h>
|
||||
#include <encoding/payloads/nonce_payload.h>
|
||||
#include <encoding/payloads/id_payload.h>
|
||||
#include <encoding/payloads/ke_payload.h>
|
||||
#include <encoding/payloads/notify_payload.h>
|
||||
#include <encoding/payloads/auth_payload.h>
|
||||
#include <encoding/payloads/cert_payload.h>
|
||||
#include <encoding/payloads/certreq_payload.h>
|
||||
#include <encoding/payloads/encryption_payload.h>
|
||||
#include <encoding/payloads/ts_payload.h>
|
||||
#include <encoding/payloads/delete_payload.h>
|
||||
#include <encoding/payloads/vendor_id_payload.h>
|
||||
#include <encoding/payloads/cp_payload.h>
|
||||
#include <encoding/payloads/configuration_attribute.h>
|
||||
#include <encoding/payloads/eap_payload.h>
|
||||
#include <encoding/payloads/unknown_payload.h>
|
||||
|
||||
/*
|
||||
* build the mappings for payload_type_t
|
||||
*/
|
||||
mapping_t payload_type_m[] = {
|
||||
{NO_PAYLOAD, "NO_PAYLOAD"},
|
||||
{SECURITY_ASSOCIATION, "SECURITY_ASSOCIATION"},
|
||||
{KEY_EXCHANGE, "KEY_EXCHANGE"},
|
||||
{ID_INITIATOR, "ID_INITIATOR"},
|
||||
{ID_RESPONDER, "ID_RESPONDER"},
|
||||
{CERTIFICATE, "CERTIFICATE"},
|
||||
{CERTIFICATE_REQUEST, "CERTIFICATE_REQUEST"},
|
||||
{AUTHENTICATION, "AUTHENTICATION"},
|
||||
{NONCE, "NONCE"},
|
||||
{NOTIFY, "NOTIFY"},
|
||||
{DELETE, "DELETE"},
|
||||
{VENDOR_ID, "VENDOR_ID"},
|
||||
{TRAFFIC_SELECTOR_INITIATOR, "TRAFFIC_SELECTOR_INITIATOR"},
|
||||
{TRAFFIC_SELECTOR_RESPONDER, "TRAFFIC_SELECTOR_RESPONDER"},
|
||||
{ENCRYPTED, "ENCRYPTED"},
|
||||
{CONFIGURATION, "CONFIGURATION"},
|
||||
{EXTENSIBLE_AUTHENTICATION, "EXTENSIBLE_AUTHENTICATION"},
|
||||
{HEADER, "HEADER"},
|
||||
{PROPOSAL_SUBSTRUCTURE, "PROPOSAL_SUBSTRUCTURE"},
|
||||
{TRANSFORM_SUBSTRUCTURE, "TRANSFORM_SUBSTRUCTURE"},
|
||||
{TRANSFORM_ATTRIBUTE, "TRANSFORM_ATTRIBUTE"},
|
||||
{TRAFFIC_SELECTOR_SUBSTRUCTURE, "TRAFFIC_SELECTOR_SUBSTRUCTURE"},
|
||||
{CONFIGURATION_ATTRIBUTE,"CONFIGURATION_ATTRIBUTE"},
|
||||
{UNKNOWN_PAYLOAD,"UNKNOWN_PAYLOAD"},
|
||||
{MAPPING_END, NULL}
|
||||
};
|
||||
|
||||
/*
|
||||
* see header
|
||||
*/
|
||||
payload_t *payload_create(payload_type_t type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case HEADER:
|
||||
return (payload_t*)ike_header_create();
|
||||
case SECURITY_ASSOCIATION:
|
||||
return (payload_t*)sa_payload_create();
|
||||
case PROPOSAL_SUBSTRUCTURE:
|
||||
return (payload_t*)proposal_substructure_create();
|
||||
case TRANSFORM_SUBSTRUCTURE:
|
||||
return (payload_t*)transform_substructure_create();
|
||||
case TRANSFORM_ATTRIBUTE:
|
||||
return (payload_t*)transform_attribute_create();
|
||||
case NONCE:
|
||||
return (payload_t*)nonce_payload_create();
|
||||
case ID_INITIATOR:
|
||||
return (payload_t*)id_payload_create(TRUE);
|
||||
case ID_RESPONDER:
|
||||
return (payload_t*)id_payload_create(FALSE);
|
||||
case AUTHENTICATION:
|
||||
return (payload_t*)auth_payload_create();
|
||||
case CERTIFICATE:
|
||||
return (payload_t*)cert_payload_create();
|
||||
case CERTIFICATE_REQUEST:
|
||||
return (payload_t*)certreq_payload_create();
|
||||
case TRAFFIC_SELECTOR_SUBSTRUCTURE:
|
||||
return (payload_t*)traffic_selector_substructure_create();
|
||||
case TRAFFIC_SELECTOR_INITIATOR:
|
||||
return (payload_t*)ts_payload_create(TRUE);
|
||||
case TRAFFIC_SELECTOR_RESPONDER:
|
||||
return (payload_t*)ts_payload_create(FALSE);
|
||||
case KEY_EXCHANGE:
|
||||
return (payload_t*)ke_payload_create();
|
||||
case NOTIFY:
|
||||
return (payload_t*)notify_payload_create();
|
||||
case DELETE:
|
||||
return (payload_t*)delete_payload_create();
|
||||
case VENDOR_ID:
|
||||
return (payload_t*)vendor_id_payload_create();
|
||||
case CONFIGURATION:
|
||||
return (payload_t*)cp_payload_create();
|
||||
case CONFIGURATION_ATTRIBUTE:
|
||||
return (payload_t*)configuration_attribute_create();
|
||||
case EXTENSIBLE_AUTHENTICATION:
|
||||
return (payload_t*)eap_payload_create();
|
||||
case ENCRYPTED:
|
||||
return (payload_t*)encryption_payload_create();
|
||||
default:
|
||||
return (payload_t*)unknown_payload_create();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,279 @@
|
||||
/**
|
||||
* @file payload.h
|
||||
*
|
||||
* @brief Interface payload_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef PAYLOAD_H_
|
||||
#define PAYLOAD_H_
|
||||
|
||||
#include <types.h>
|
||||
#include <definitions.h>
|
||||
#include <encoding/payloads/encodings.h>
|
||||
|
||||
|
||||
typedef enum payload_type_t payload_type_t;
|
||||
|
||||
/**
|
||||
* @brief Payload-Types of a IKEv2-Message.
|
||||
*
|
||||
* Header and substructures are also defined as
|
||||
* payload types with values from PRIVATE USE space.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
enum payload_type_t{
|
||||
|
||||
/**
|
||||
* End of payload list in next_payload
|
||||
*/
|
||||
NO_PAYLOAD = 0,
|
||||
|
||||
/**
|
||||
* The security association (SA) payload containing proposals.
|
||||
*/
|
||||
SECURITY_ASSOCIATION = 33,
|
||||
|
||||
/**
|
||||
* The key exchange (KE) payload containing diffie-hellman values.
|
||||
*/
|
||||
KEY_EXCHANGE = 34,
|
||||
|
||||
/**
|
||||
* Identification for the original initiator (IDi).
|
||||
*/
|
||||
ID_INITIATOR = 35,
|
||||
|
||||
/**
|
||||
* Identification for the original responder (IDr).
|
||||
*/
|
||||
ID_RESPONDER = 36,
|
||||
|
||||
/**
|
||||
* Certificate payload with certificates (CERT).
|
||||
*/
|
||||
CERTIFICATE = 37,
|
||||
|
||||
/**
|
||||
* Certificate request payload (CERTREQ).
|
||||
*/
|
||||
CERTIFICATE_REQUEST = 38,
|
||||
|
||||
/**
|
||||
* Authentication payload contains auth data (AUTH).
|
||||
*/
|
||||
AUTHENTICATION = 39,
|
||||
|
||||
/**
|
||||
* Nonces, for initator and responder (Ni, Nr, N)
|
||||
*/
|
||||
NONCE = 40,
|
||||
|
||||
/**
|
||||
* Notif paylaod (N).
|
||||
*/
|
||||
NOTIFY = 41,
|
||||
|
||||
/**
|
||||
* Delete payload (D)
|
||||
*/
|
||||
DELETE = 42,
|
||||
|
||||
/**
|
||||
* Vendor id paylpoad (V).
|
||||
*/
|
||||
VENDOR_ID = 43,
|
||||
|
||||
/**
|
||||
* Traffic selector for the original initiator (TSi).
|
||||
*/
|
||||
TRAFFIC_SELECTOR_INITIATOR = 44,
|
||||
|
||||
/**
|
||||
* Traffic selector for the original responser (TSr).
|
||||
*/
|
||||
TRAFFIC_SELECTOR_RESPONDER = 45,
|
||||
|
||||
/**
|
||||
* Encryption payload, contains other payloads (E).
|
||||
*/
|
||||
ENCRYPTED = 46,
|
||||
|
||||
/**
|
||||
* Configuration payload (CP).
|
||||
*/
|
||||
CONFIGURATION = 47,
|
||||
|
||||
/**
|
||||
* Extensible authentication payload (EAP).
|
||||
*/
|
||||
EXTENSIBLE_AUTHENTICATION = 48,
|
||||
|
||||
/**
|
||||
* Header has a value of PRIVATE USE space.
|
||||
*
|
||||
* This payload type is not send over wire and just
|
||||
* used internally to handle IKEv2-Header like a payload.
|
||||
*/
|
||||
HEADER = 140,
|
||||
|
||||
/**
|
||||
* PROPOSAL_SUBSTRUCTURE has a value of PRIVATE USE space.
|
||||
*
|
||||
* This payload type is not send over wire and just
|
||||
* used internally to handle a proposal substructure like a payload.
|
||||
*/
|
||||
PROPOSAL_SUBSTRUCTURE = 141,
|
||||
|
||||
/**
|
||||
* TRANSFORM_SUBSTRUCTURE has a value of PRIVATE USE space.
|
||||
*
|
||||
* This payload type is not send over wire and just
|
||||
* used internally to handle a transform substructure like a payload.
|
||||
*/
|
||||
TRANSFORM_SUBSTRUCTURE = 142,
|
||||
|
||||
/**
|
||||
* TRANSFORM_ATTRIBUTE has a value of PRIVATE USE space.
|
||||
*
|
||||
* This payload type is not send over wire and just
|
||||
* used internally to handle a transform attribute like a payload.
|
||||
*/
|
||||
TRANSFORM_ATTRIBUTE = 143,
|
||||
|
||||
/**
|
||||
* TRAFFIC_SELECTOR_SUBSTRUCTURE has a value of PRIVATE USE space.
|
||||
*
|
||||
* This payload type is not send over wire and just
|
||||
* used internally to handle a transform selector like a payload.
|
||||
*/
|
||||
TRAFFIC_SELECTOR_SUBSTRUCTURE = 144,
|
||||
|
||||
/**
|
||||
* CONFIGURATION_ATTRIBUTE has a value of PRIVATE USE space.
|
||||
*
|
||||
* This payload type is not send over wire and just
|
||||
* used internally to handle a transform attribute like a payload.
|
||||
*/
|
||||
CONFIGURATION_ATTRIBUTE = 145,
|
||||
|
||||
/**
|
||||
* A unknown payload has a value of PRIVATE USE space.
|
||||
*
|
||||
* This payload type is not send over wire and just
|
||||
* used internally to handle a unknown payload.
|
||||
*/
|
||||
UNKNOWN_PAYLOAD = 146,
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* String mappings for payload_type_t.
|
||||
*/
|
||||
extern mapping_t payload_type_m[];
|
||||
|
||||
|
||||
typedef struct payload_t payload_t;
|
||||
|
||||
/**
|
||||
* @brief Generic interface for all payload types (incl.header and substructures).
|
||||
*
|
||||
* To handle all kinds of payloads on a generic way, this interface must
|
||||
* be implemented by every payload. This allows parser_t/generator_t a simple
|
||||
* handling of all payloads.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - payload_create() with the payload to instanciate.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
struct payload_t {
|
||||
|
||||
/**
|
||||
* @brief Get encoding rules for this payload.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param[out] rules location to store pointer of first rule
|
||||
* @param[out] rule_count location to store number of rules
|
||||
*/
|
||||
void (*get_encoding_rules) (payload_t *this, encoding_rule_t **rules, size_t *rule_count);
|
||||
|
||||
/**
|
||||
* @brief Get type of payload.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return type of this payload
|
||||
*/
|
||||
payload_type_t (*get_type) (payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get type of next payload or NO_PAYLOAD (0) if this is the last one.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return type of next payload
|
||||
*/
|
||||
payload_type_t (*get_next_type) (payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Set type of next payload.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param type type of next payload
|
||||
*/
|
||||
void (*set_next_type) (payload_t *this,payload_type_t type);
|
||||
|
||||
/**
|
||||
* @brief Get length of payload.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return length of this payload
|
||||
*/
|
||||
size_t (*get_length) (payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Verifies payload structure and makes consistence check.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return
|
||||
* - SUCCESS
|
||||
* - FAILED if consistence not given
|
||||
*/
|
||||
status_t (*verify) (payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Destroys a payload and all included substructures.
|
||||
*
|
||||
* @param this payload to destroy
|
||||
*/
|
||||
void (*destroy) (payload_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Create an empty payload.
|
||||
*
|
||||
* Useful for the parser, who wants a generic constructor for all payloads.
|
||||
* It supports all payload_t methods. If a payload type is not known,
|
||||
* an unknwon_paylod is created with the chunk of data in it.
|
||||
*
|
||||
* @param type type of the payload to create
|
||||
* @return payload_t object
|
||||
*/
|
||||
payload_t *payload_create(payload_type_t type);
|
||||
|
||||
#endif /*PAYLOAD_H_*/
|
||||
@@ -0,0 +1,629 @@
|
||||
/**
|
||||
* @file proposal_substructure.h
|
||||
*
|
||||
* @brief Implementation of proposal_substructure_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "proposal_substructure.h"
|
||||
|
||||
#include <encoding/payloads/encodings.h>
|
||||
#include <encoding/payloads/transform_substructure.h>
|
||||
#include <types.h>
|
||||
#include <utils/linked_list.h>
|
||||
|
||||
|
||||
/**
|
||||
* IKEv1 Value for a proposal payload.
|
||||
*/
|
||||
#define PROPOSAL_TYPE_VALUE 2
|
||||
|
||||
|
||||
typedef struct private_proposal_substructure_t private_proposal_substructure_t;
|
||||
|
||||
/**
|
||||
* Private data of an proposal_substructure_t object.
|
||||
*
|
||||
*/
|
||||
struct private_proposal_substructure_t {
|
||||
/**
|
||||
* Public proposal_substructure_t interface.
|
||||
*/
|
||||
proposal_substructure_t public;
|
||||
|
||||
/**
|
||||
* Next payload type.
|
||||
*/
|
||||
u_int8_t next_payload;
|
||||
|
||||
/**
|
||||
* Length of this payload.
|
||||
*/
|
||||
u_int16_t proposal_length;
|
||||
|
||||
/**
|
||||
* Proposal number.
|
||||
*/
|
||||
u_int8_t proposal_number;
|
||||
|
||||
/**
|
||||
* Protocol ID.
|
||||
*/
|
||||
u_int8_t protocol_id;
|
||||
|
||||
/**
|
||||
* SPI size of the following SPI.
|
||||
*/
|
||||
u_int8_t spi_size;
|
||||
|
||||
/**
|
||||
* Number of transforms.
|
||||
*/
|
||||
u_int8_t transforms_count;
|
||||
|
||||
/**
|
||||
* SPI is stored as chunk.
|
||||
*/
|
||||
chunk_t spi;
|
||||
|
||||
/**
|
||||
* Transforms are stored in a linked_list_t.
|
||||
*/
|
||||
linked_list_t * transforms;
|
||||
|
||||
/**
|
||||
* @brief Computes the length of this substructure.
|
||||
*
|
||||
* @param this calling private_proposal_substructure_t object
|
||||
*/
|
||||
void (*compute_length) (private_proposal_substructure_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Encoding rules to parse or generate a Proposal substructure.
|
||||
*
|
||||
* The defined offsets are the positions in a object of type
|
||||
* private_proposal_substructure_t.
|
||||
*
|
||||
*/
|
||||
encoding_rule_t proposal_substructure_encodings[] = {
|
||||
/* 1 Byte next payload type, stored in the field next_payload */
|
||||
{ U_INT_8, offsetof(private_proposal_substructure_t, next_payload) },
|
||||
/* Reserved Byte is skipped */
|
||||
{ RESERVED_BYTE, 0 },
|
||||
/* Length of the whole proposal substructure payload*/
|
||||
{ PAYLOAD_LENGTH, offsetof(private_proposal_substructure_t, proposal_length) },
|
||||
/* proposal number is a number of 8 bit */
|
||||
{ U_INT_8, offsetof(private_proposal_substructure_t, proposal_number) },
|
||||
/* protocol ID is a number of 8 bit */
|
||||
{ U_INT_8, offsetof(private_proposal_substructure_t, protocol_id) },
|
||||
/* SPI Size has its own type */
|
||||
{ SPI_SIZE, offsetof(private_proposal_substructure_t, spi_size) },
|
||||
/* Number of transforms is a number of 8 bit */
|
||||
{ U_INT_8, offsetof(private_proposal_substructure_t, transforms_count) },
|
||||
/* SPI is a chunk of variable size*/
|
||||
{ SPI, offsetof(private_proposal_substructure_t, spi) },
|
||||
/* Transforms are stored in a transform substructure,
|
||||
offset points to a linked_list_t pointer */
|
||||
{ TRANSFORMS, offsetof(private_proposal_substructure_t, transforms) }
|
||||
};
|
||||
|
||||
/*
|
||||
1 2 3
|
||||
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
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! 0 (last) or 2 ! RESERVED ! Proposal Length !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! Proposal # ! Protocol ID ! SPI Size !# of Transforms!
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
~ SPI (variable) ~
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! !
|
||||
~ <Transforms> ~
|
||||
! !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.verify.
|
||||
*/
|
||||
static status_t verify(private_proposal_substructure_t *this)
|
||||
{
|
||||
status_t status = SUCCESS;
|
||||
iterator_t *iterator;
|
||||
|
||||
if ((this->next_payload != NO_PAYLOAD) && (this->next_payload != 2))
|
||||
{
|
||||
/* must be 0 or 2 */
|
||||
return FAILED;
|
||||
}
|
||||
if (this->transforms_count != this->transforms->get_count(this->transforms))
|
||||
{
|
||||
/* must be the same! */
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
if ((this->protocol_id == 0) || (this->protocol_id >= 4))
|
||||
{
|
||||
/* reserved are not supported */
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
iterator = this->transforms->create_iterator(this->transforms,TRUE);
|
||||
|
||||
while(iterator->has_next(iterator))
|
||||
{
|
||||
payload_t *current_transform;
|
||||
iterator->current(iterator,(void **)¤t_transform);
|
||||
|
||||
status = current_transform->verify(current_transform);
|
||||
if (status != SUCCESS)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
iterator->destroy(iterator);
|
||||
|
||||
|
||||
/* proposal number is checked in SA payload */
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_encoding_rules.
|
||||
*/
|
||||
static void get_encoding_rules(private_proposal_substructure_t *this, encoding_rule_t **rules, size_t *rule_count)
|
||||
{
|
||||
*rules = proposal_substructure_encodings;
|
||||
*rule_count = sizeof(proposal_substructure_encodings) / sizeof(encoding_rule_t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_type.
|
||||
*/
|
||||
static payload_type_t get_type(private_proposal_substructure_t *this)
|
||||
{
|
||||
return PROPOSAL_SUBSTRUCTURE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_next_type.
|
||||
*/
|
||||
static payload_type_t get_next_type(private_proposal_substructure_t *this)
|
||||
{
|
||||
return (this->next_payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.set_next_type.
|
||||
*/
|
||||
static void set_next_type(private_proposal_substructure_t *this,payload_type_t type)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_length.
|
||||
*/
|
||||
static size_t get_length(private_proposal_substructure_t *this)
|
||||
{
|
||||
this->compute_length(this);
|
||||
return this->proposal_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of proposal_substructure_t.create_transform_substructure_iterator.
|
||||
*/
|
||||
static iterator_t *create_transform_substructure_iterator (private_proposal_substructure_t *this,bool forward)
|
||||
{
|
||||
return (this->transforms->create_iterator(this->transforms,forward));
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of proposal_substructure_t.add_transform_substructure.
|
||||
*/
|
||||
static void add_transform_substructure (private_proposal_substructure_t *this,transform_substructure_t *transform)
|
||||
{
|
||||
status_t status;
|
||||
if (this->transforms->get_count(this->transforms) > 0)
|
||||
{
|
||||
transform_substructure_t *last_transform;
|
||||
status = this->transforms->get_last(this->transforms,(void **) &last_transform);
|
||||
/* last transform is now not anymore last one */
|
||||
last_transform->set_is_last_transform(last_transform,FALSE);
|
||||
|
||||
}
|
||||
transform->set_is_last_transform(transform,TRUE);
|
||||
|
||||
this->transforms->insert_last(this->transforms,(void *) transform);
|
||||
this->compute_length(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of proposal_substructure_t.proposal_substructure_t.
|
||||
*/
|
||||
static void set_is_last_proposal (private_proposal_substructure_t *this, bool is_last)
|
||||
{
|
||||
this->next_payload = (is_last) ? 0: PROPOSAL_TYPE_VALUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of proposal_substructure_t.set_proposal_number.
|
||||
*/
|
||||
static void set_proposal_number(private_proposal_substructure_t *this,u_int8_t proposal_number)
|
||||
{
|
||||
this->proposal_number = proposal_number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of proposal_substructure_t.get_proposal_number.
|
||||
*/
|
||||
static u_int8_t get_proposal_number (private_proposal_substructure_t *this)
|
||||
{
|
||||
return (this->proposal_number);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of proposal_substructure_t.set_protocol_id.
|
||||
*/
|
||||
static void set_protocol_id(private_proposal_substructure_t *this,u_int8_t protocol_id)
|
||||
{
|
||||
this->protocol_id = protocol_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of proposal_substructure_t.get_protocol_id.
|
||||
*/
|
||||
static u_int8_t get_protocol_id (private_proposal_substructure_t *this)
|
||||
{
|
||||
return (this->protocol_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of proposal_substructure_t.set_spi.
|
||||
*/
|
||||
static void set_spi (private_proposal_substructure_t *this, chunk_t spi)
|
||||
{
|
||||
/* first delete already set spi value */
|
||||
if (this->spi.ptr != NULL)
|
||||
{
|
||||
free(this->spi.ptr);
|
||||
this->spi.ptr = NULL;
|
||||
this->spi.len = 0;
|
||||
this->compute_length(this);
|
||||
}
|
||||
|
||||
this->spi.ptr = clalloc(spi.ptr,spi.len);
|
||||
this->spi.len = spi.len;
|
||||
this->spi_size = spi.len;
|
||||
this->compute_length(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of proposal_substructure_t.get_spi.
|
||||
*/
|
||||
static chunk_t get_spi (private_proposal_substructure_t *this)
|
||||
{
|
||||
chunk_t spi;
|
||||
spi.ptr = this->spi.ptr;
|
||||
spi.len = this->spi.len;
|
||||
|
||||
return spi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of proposal_substructure_t.get_info_for_transform_type.
|
||||
*/
|
||||
static status_t get_info_for_transform_type (private_proposal_substructure_t *this,transform_type_t type, u_int16_t *transform_id, u_int16_t *key_length)
|
||||
{
|
||||
iterator_t *iterator;
|
||||
status_t status;
|
||||
u_int16_t found_transform_id;
|
||||
u_int16_t found_key_length;
|
||||
|
||||
iterator = this->transforms->create_iterator(this->transforms,TRUE);
|
||||
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
transform_substructure_t *current_transform;
|
||||
status = iterator->current(iterator,(void **) ¤t_transform);
|
||||
if (status != SUCCESS)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (current_transform->get_transform_type(current_transform) == type)
|
||||
{
|
||||
/* now get data for specific type */
|
||||
found_transform_id = current_transform->get_transform_id(current_transform);
|
||||
status = current_transform->get_key_length(current_transform,&found_key_length);
|
||||
*transform_id = found_transform_id;
|
||||
*key_length = found_key_length;
|
||||
iterator->destroy(iterator);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
return NOT_FOUND;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of private_proposal_substructure_t.compute_length.
|
||||
*/
|
||||
static void compute_length (private_proposal_substructure_t *this)
|
||||
{
|
||||
iterator_t *iterator;
|
||||
size_t transforms_count = 0;
|
||||
size_t length = PROPOSAL_SUBSTRUCTURE_HEADER_LENGTH;
|
||||
iterator = this->transforms->create_iterator(this->transforms,TRUE);
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
payload_t * current_transform;
|
||||
iterator->current(iterator,(void **) ¤t_transform);
|
||||
length += current_transform->get_length(current_transform);
|
||||
transforms_count++;
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
length += this->spi.len;
|
||||
this->transforms_count = transforms_count;
|
||||
this->proposal_length = length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of proposal_substructure_t.get_transform_count.
|
||||
*/
|
||||
static size_t get_transform_count (private_proposal_substructure_t *this)
|
||||
{
|
||||
return this->transforms->get_count(this->transforms);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of proposal_substructure_t.get_spi_size.
|
||||
*/
|
||||
static size_t get_spi_size (private_proposal_substructure_t *this)
|
||||
{
|
||||
return this->spi.len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of proposal_substructure_t.add_to_proposal.
|
||||
*/
|
||||
void add_to_proposal(private_proposal_substructure_t *this, proposal_t *proposal)
|
||||
{
|
||||
iterator_t *iterator = this->transforms->create_iterator(this->transforms, TRUE);
|
||||
u_int32_t spi;
|
||||
|
||||
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
transform_substructure_t *transform;
|
||||
transform_type_t transform_type;
|
||||
u_int16_t transform_id;
|
||||
u_int16_t key_length = 0;
|
||||
|
||||
iterator->current(iterator, (void**)&transform);
|
||||
|
||||
transform_type = transform->get_transform_type(transform);
|
||||
transform_id = transform->get_transform_id(transform);
|
||||
transform->get_key_length(transform, &key_length);
|
||||
|
||||
proposal->add_algorithm(proposal, this->protocol_id, transform_type, transform_id, key_length);
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
spi = *((u_int32_t*)this->spi.ptr);
|
||||
|
||||
proposal->set_spi(proposal, this->protocol_id, spi);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of proposal_substructure_t.clone.
|
||||
*/
|
||||
static private_proposal_substructure_t* clone(private_proposal_substructure_t *this)
|
||||
{
|
||||
private_proposal_substructure_t * new_clone;
|
||||
iterator_t *transforms;
|
||||
|
||||
new_clone = (private_proposal_substructure_t *) proposal_substructure_create();
|
||||
|
||||
new_clone->next_payload = this->next_payload;
|
||||
new_clone->proposal_number = this->proposal_number;
|
||||
new_clone->protocol_id = this->protocol_id;
|
||||
new_clone->spi_size = this->spi_size;
|
||||
if (this->spi.ptr != NULL)
|
||||
{
|
||||
new_clone->spi.ptr = clalloc(this->spi.ptr,this->spi.len);
|
||||
new_clone->spi.len = this->spi.len;
|
||||
}
|
||||
|
||||
transforms = this->transforms->create_iterator(this->transforms,FALSE);
|
||||
|
||||
while (transforms->has_next(transforms))
|
||||
{
|
||||
transform_substructure_t *current_transform;
|
||||
transform_substructure_t *current_transform_clone;
|
||||
|
||||
transforms->current(transforms,(void **) ¤t_transform);
|
||||
|
||||
current_transform_clone = current_transform->clone(current_transform);
|
||||
|
||||
new_clone->public.add_transform_substructure(&(new_clone->public),current_transform_clone);
|
||||
}
|
||||
|
||||
transforms->destroy(transforms);
|
||||
|
||||
return new_clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements payload_t's and proposal_substructure_t's destroy function.
|
||||
* See #payload_s.destroy or proposal_substructure_s.destroy for description.
|
||||
*/
|
||||
static status_t destroy(private_proposal_substructure_t *this)
|
||||
{
|
||||
/* all proposals are getting destroyed */
|
||||
while (this->transforms->get_count(this->transforms) > 0)
|
||||
{
|
||||
transform_substructure_t *current_transform;
|
||||
if (this->transforms->remove_last(this->transforms,(void **)¤t_transform) != SUCCESS)
|
||||
{
|
||||
break;
|
||||
}
|
||||
current_transform->destroy(current_transform);
|
||||
}
|
||||
this->transforms->destroy(this->transforms);
|
||||
|
||||
if (this->spi.ptr != NULL)
|
||||
{
|
||||
free(this->spi.ptr);
|
||||
}
|
||||
|
||||
free(this);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
proposal_substructure_t *proposal_substructure_create()
|
||||
{
|
||||
private_proposal_substructure_t *this = malloc_thing(private_proposal_substructure_t);
|
||||
|
||||
/* interface functions */
|
||||
this->public.payload_interface.verify = (status_t (*) (payload_t *))verify;
|
||||
this->public.payload_interface.get_encoding_rules = (void (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules;
|
||||
this->public.payload_interface.get_length = (size_t (*) (payload_t *)) get_length;
|
||||
this->public.payload_interface.get_next_type = (payload_type_t (*) (payload_t *)) get_next_type;
|
||||
this->public.payload_interface.set_next_type = (void (*) (payload_t *,payload_type_t)) set_next_type;
|
||||
this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_type;
|
||||
this->public.payload_interface.destroy = (void (*) (payload_t *))destroy;
|
||||
|
||||
|
||||
/* public functions */
|
||||
this->public.create_transform_substructure_iterator = (iterator_t* (*) (proposal_substructure_t *,bool)) create_transform_substructure_iterator;
|
||||
this->public.add_transform_substructure = (void (*) (proposal_substructure_t *,transform_substructure_t *)) add_transform_substructure;
|
||||
this->public.set_proposal_number = (void (*) (proposal_substructure_t *,u_int8_t))set_proposal_number;
|
||||
this->public.get_proposal_number = (u_int8_t (*) (proposal_substructure_t *)) get_proposal_number;
|
||||
this->public.set_protocol_id = (void (*) (proposal_substructure_t *,u_int8_t))set_protocol_id;
|
||||
this->public.get_protocol_id = (u_int8_t (*) (proposal_substructure_t *)) get_protocol_id;
|
||||
this->public.get_info_for_transform_type = (status_t (*) (proposal_substructure_t *,transform_type_t,u_int16_t *, u_int16_t *))get_info_for_transform_type;
|
||||
this->public.set_is_last_proposal = (void (*) (proposal_substructure_t *,bool)) set_is_last_proposal;
|
||||
this->public.add_to_proposal = (void (*) (proposal_substructure_t*,proposal_t*))add_to_proposal;
|
||||
this->public.set_spi = (void (*) (proposal_substructure_t *,chunk_t))set_spi;
|
||||
this->public.get_spi = (chunk_t (*) (proposal_substructure_t *)) get_spi;
|
||||
this->public.get_transform_count = (size_t (*) (proposal_substructure_t *)) get_transform_count;
|
||||
this->public.get_spi_size = (size_t (*) (proposal_substructure_t *)) get_spi_size;
|
||||
this->public.clone = (proposal_substructure_t * (*) (proposal_substructure_t *)) clone;
|
||||
this->public.destroy = (void (*) (proposal_substructure_t *)) destroy;
|
||||
|
||||
/* private functions */
|
||||
this->compute_length = compute_length;
|
||||
|
||||
/* set default values of the fields */
|
||||
this->next_payload = NO_PAYLOAD;
|
||||
this->proposal_length = 0;
|
||||
this->proposal_number = 0;
|
||||
this->protocol_id = 0;
|
||||
this->transforms_count = 0;
|
||||
this->spi_size = 0;
|
||||
this->spi.ptr = NULL;
|
||||
this->spi.len = 0;
|
||||
|
||||
this->transforms = linked_list_create();
|
||||
|
||||
return (&(this->public));
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
proposal_substructure_t *proposal_substructure_create_from_proposal(proposal_t *proposal, protocol_id_t proto)
|
||||
{
|
||||
private_proposal_substructure_t *this = (private_proposal_substructure_t*)proposal_substructure_create();
|
||||
iterator_t *iterator;
|
||||
algorithm_t *algo;
|
||||
transform_substructure_t *transform;
|
||||
|
||||
/* encryption algorithm is only availble in ESP */
|
||||
iterator = proposal->create_algorithm_iterator(proposal, proto, ENCRYPTION_ALGORITHM);
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
iterator->current(iterator, (void**)&algo);
|
||||
transform = transform_substructure_create_type(ENCRYPTION_ALGORITHM, algo->algorithm, algo->key_size);
|
||||
this->public.add_transform_substructure(&(this->public), transform);
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
/* integrity algorithms */
|
||||
iterator = proposal->create_algorithm_iterator(proposal, proto, INTEGRITY_ALGORITHM);
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
algorithm_t *algo;
|
||||
iterator->current(iterator, (void**)&algo);
|
||||
transform = transform_substructure_create_type(INTEGRITY_ALGORITHM, algo->algorithm, algo->key_size);
|
||||
this->public.add_transform_substructure(&(this->public), transform);
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
/* prf algorithms */
|
||||
iterator = proposal->create_algorithm_iterator(proposal, proto, PSEUDO_RANDOM_FUNCTION);
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
algorithm_t *algo;
|
||||
iterator->current(iterator, (void**)&algo);
|
||||
transform = transform_substructure_create_type(PSEUDO_RANDOM_FUNCTION, algo->algorithm, algo->key_size);
|
||||
this->public.add_transform_substructure(&(this->public), transform);
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
/* dh groups */
|
||||
iterator = proposal->create_algorithm_iterator(proposal, proto, DIFFIE_HELLMAN_GROUP);
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
algorithm_t *algo;
|
||||
iterator->current(iterator, (void**)&algo);
|
||||
transform = transform_substructure_create_type(DIFFIE_HELLMAN_GROUP, algo->algorithm, 0);
|
||||
this->public.add_transform_substructure(&(this->public), transform);
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
/* extended sequence numbers */
|
||||
iterator = proposal->create_algorithm_iterator(proposal, proto, EXTENDED_SEQUENCE_NUMBERS);
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
algorithm_t *algo;
|
||||
iterator->current(iterator, (void**)&algo);
|
||||
transform = transform_substructure_create_type(EXTENDED_SEQUENCE_NUMBERS, algo->algorithm, 0);
|
||||
this->public.add_transform_substructure(&(this->public), transform);
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
/* take over general infos */
|
||||
this->spi_size = proto == PROTO_IKE ? 8 : 4;
|
||||
this->spi.len = this->spi_size;
|
||||
this->spi.ptr = malloc(this->spi_size);
|
||||
*((u_int32_t*)this->spi.ptr) = proposal->get_spi(proposal, proto);
|
||||
this->proposal_number = proposal->get_number(proposal);
|
||||
this->protocol_id = proto;
|
||||
|
||||
return &(this->public);
|
||||
}
|
||||
@@ -0,0 +1,231 @@
|
||||
/**
|
||||
* @file proposal_substructure.h
|
||||
*
|
||||
* @brief Interface of proposal_substructure_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef PROPOSAL_SUBSTRUCTURE_H_
|
||||
#define PROPOSAL_SUBSTRUCTURE_H_
|
||||
|
||||
#include <types.h>
|
||||
#include <encoding/payloads/payload.h>
|
||||
#include <encoding/payloads/transform_substructure.h>
|
||||
#include <config/proposal.h>
|
||||
#include <utils/linked_list.h>
|
||||
|
||||
|
||||
/**
|
||||
* Length of the proposal substructure header (without spi).
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
#define PROPOSAL_SUBSTRUCTURE_HEADER_LENGTH 8
|
||||
|
||||
|
||||
typedef struct proposal_substructure_t proposal_substructure_t;
|
||||
|
||||
/**
|
||||
* @brief Class representing an IKEv2-PROPOSAL SUBSTRUCTURE.
|
||||
*
|
||||
* The PROPOSAL SUBSTRUCTURE format is described in RFC section 3.3.1.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - proposal_substructure_create()
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
struct proposal_substructure_t {
|
||||
/**
|
||||
* The payload_t interface.
|
||||
*/
|
||||
payload_t payload_interface;
|
||||
|
||||
/**
|
||||
* @brief Creates an iterator of stored transform_substructure_t objects.
|
||||
*
|
||||
* @warning The created iterator has to get destroyed by the caller!
|
||||
* When deleting any transform over this iterator, call
|
||||
* get_size to make sure the length and number values are ok.
|
||||
*
|
||||
* @param this calling proposal_substructure_t object
|
||||
* @param forward iterator direction (TRUE: front to end)
|
||||
* @return created iterator_t object
|
||||
*/
|
||||
iterator_t * (*create_transform_substructure_iterator) (proposal_substructure_t *this, bool forward);
|
||||
|
||||
/**
|
||||
* @brief Adds a transform_substructure_t object to this object.
|
||||
*
|
||||
* @warning The added transform_substructure_t object is
|
||||
* getting destroyed in destroy function of proposal_substructure_t.
|
||||
*
|
||||
* @param this calling proposal_substructure_t object
|
||||
* @param transform transform_substructure_t object to add
|
||||
*/
|
||||
void (*add_transform_substructure) (proposal_substructure_t *this,transform_substructure_t *transform);
|
||||
|
||||
/**
|
||||
* @brief Sets the proposal number of current proposal.
|
||||
*
|
||||
* @param this calling proposal_substructure_t object
|
||||
* @param id proposal number to set
|
||||
*/
|
||||
void (*set_proposal_number) (proposal_substructure_t *this,u_int8_t proposal_number);
|
||||
|
||||
/**
|
||||
* @brief get proposal number of current proposal.
|
||||
*
|
||||
* @param this calling proposal_substructure_t object
|
||||
* @return proposal number of current proposal substructure.
|
||||
*/
|
||||
u_int8_t (*get_proposal_number) (proposal_substructure_t *this);
|
||||
|
||||
/**
|
||||
* @brief get the number of transforms in current proposal.
|
||||
*
|
||||
* @param this calling proposal_substructure_t object
|
||||
* @return transform count in current proposal
|
||||
*/
|
||||
size_t (*get_transform_count) (proposal_substructure_t *this);
|
||||
|
||||
/**
|
||||
* @brief get size of the set spi in bytes.
|
||||
*
|
||||
* @param this calling proposal_substructure_t object
|
||||
* @return size of the spi in bytes
|
||||
*/
|
||||
size_t (*get_spi_size) (proposal_substructure_t *this);
|
||||
|
||||
/**
|
||||
* @brief Sets the protocol id of current proposal.
|
||||
*
|
||||
* @param this calling proposal_substructure_t object
|
||||
* @param id protocol id to set
|
||||
*/
|
||||
void (*set_protocol_id) (proposal_substructure_t *this,u_int8_t protocol_id);
|
||||
|
||||
/**
|
||||
* @brief get protocol id of current proposal.
|
||||
*
|
||||
* @param this calling proposal_substructure_t object
|
||||
* @return protocol id of current proposal substructure.
|
||||
*/
|
||||
u_int8_t (*get_protocol_id) (proposal_substructure_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get informations for a specific transform type.
|
||||
*
|
||||
* @param this calling proposal_substructure_t object
|
||||
* @param type type to get informations for
|
||||
* @param transform_id transform id of the specific type
|
||||
* @param key_length key length of the specific key length transform attribute
|
||||
* @return
|
||||
* - SUCCESS if transform type is part of this proposal and
|
||||
* all data (incl. key length) could be fetched
|
||||
* - NOT_FOUND if transform type is not part of this proposal
|
||||
*/
|
||||
status_t (*get_info_for_transform_type) (proposal_substructure_t *this,transform_type_t type, u_int16_t *transform_id, u_int16_t *key_length);
|
||||
|
||||
/**
|
||||
* @brief Sets the next_payload field of this substructure
|
||||
*
|
||||
* If this is the last proposal, next payload field is set to 0,
|
||||
* otherwise to 2
|
||||
*
|
||||
* @param this calling proposal_substructure_t object
|
||||
* @param is_last When TRUE, next payload field is set to 0, otherwise to 2
|
||||
*/
|
||||
void (*set_is_last_proposal) (proposal_substructure_t *this, bool is_last);
|
||||
|
||||
/**
|
||||
* @brief Returns the currently set SPI of this proposal.
|
||||
*
|
||||
* @warning Returned data are not copied
|
||||
*
|
||||
* @param this calling proposal_substructure_t object
|
||||
* @return chunk_t pointing to the value
|
||||
*/
|
||||
chunk_t (*get_spi) (proposal_substructure_t *this);
|
||||
|
||||
/**
|
||||
* @brief Sets the SPI of the current proposal.
|
||||
*
|
||||
* @warning SPI is getting copied
|
||||
*
|
||||
* @param this calling proposal_substructure_t object
|
||||
* @param spi chunk_t pointing to the value to set
|
||||
*/
|
||||
void (*set_spi) (proposal_substructure_t *this, chunk_t spi);
|
||||
|
||||
/**
|
||||
* @brief Add this proposal_substructure to a proposal.
|
||||
*
|
||||
* Since a proposal_t may contain the data of multiple
|
||||
* proposal_sbustructure_t's, it may be necessary to call
|
||||
* the function multiple times with the same proposal.
|
||||
*
|
||||
* @param this calling proposal_substructure_t object
|
||||
* @param proposal proposal where the data should be added
|
||||
*/
|
||||
void (*add_to_proposal) (proposal_substructure_t *this, proposal_t *proposal);
|
||||
|
||||
/**
|
||||
* @brief Clones an proposal_substructure_t object.
|
||||
*
|
||||
* @param this proposal_substructure_t object to clone
|
||||
* @return cloned object
|
||||
*/
|
||||
proposal_substructure_t* (*clone) (proposal_substructure_t *this);
|
||||
|
||||
/**
|
||||
* @brief Destroys an proposal_substructure_t object.
|
||||
*
|
||||
* @param this proposal_substructure_t object to destroy
|
||||
*/
|
||||
void (*destroy) (proposal_substructure_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Creates an empty proposal_substructure_t object
|
||||
*
|
||||
* @return proposal_substructure_t object
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
proposal_substructure_t *proposal_substructure_create();
|
||||
|
||||
/**
|
||||
* @brief Creates a proposal substructure from a proposal.
|
||||
*
|
||||
* Since a child proposal may contain data for both AH and ESP,
|
||||
* the protocol must be specified. If the proposal does not contain
|
||||
* data for proto, NULL is returned. Call twice, once with AH, once
|
||||
* with ESP, with the same proposal to build the two substructures
|
||||
* for it.
|
||||
*
|
||||
* @param proposal proposal to build a substruct out of it
|
||||
* @param proto for which protocol the substructure should be built
|
||||
* @return proposal_substructure_t object, or NULL
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
proposal_substructure_t *proposal_substructure_create_from_proposal(proposal_t *proposal, protocol_id_t proto);
|
||||
|
||||
|
||||
#endif /*PROPOSAL_SUBSTRUCTURE_H_*/
|
||||
@@ -0,0 +1,390 @@
|
||||
/**
|
||||
* @file sa_payload.c
|
||||
*
|
||||
* @brief Implementation of sa_payload_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "sa_payload.h"
|
||||
|
||||
#include <encoding/payloads/encodings.h>
|
||||
#include <utils/linked_list.h>
|
||||
|
||||
|
||||
typedef struct private_sa_payload_t private_sa_payload_t;
|
||||
|
||||
/**
|
||||
* Private data of an sa_payload_t object.
|
||||
*
|
||||
*/
|
||||
struct private_sa_payload_t {
|
||||
/**
|
||||
* Public sa_payload_t interface.
|
||||
*/
|
||||
sa_payload_t public;
|
||||
|
||||
/**
|
||||
* Next payload type.
|
||||
*/
|
||||
u_int8_t next_payload;
|
||||
|
||||
/**
|
||||
* Critical flag.
|
||||
*/
|
||||
bool critical;
|
||||
|
||||
/**
|
||||
* Length of this payload.
|
||||
*/
|
||||
u_int16_t payload_length;
|
||||
|
||||
/**
|
||||
* Proposals in this payload are stored in a linked_list_t.
|
||||
*/
|
||||
linked_list_t * proposals;
|
||||
|
||||
/**
|
||||
* @brief Computes the length of this payload.
|
||||
*
|
||||
* @param this calling private_sa_payload_t object
|
||||
*/
|
||||
void (*compute_length) (private_sa_payload_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Encoding rules to parse or generate a IKEv2-SA Payload
|
||||
*
|
||||
* The defined offsets are the positions in a object of type
|
||||
* private_sa_payload_t.
|
||||
*
|
||||
*/
|
||||
encoding_rule_t sa_payload_encodings[] = {
|
||||
/* 1 Byte next payload type, stored in the field next_payload */
|
||||
{ U_INT_8, offsetof(private_sa_payload_t, next_payload) },
|
||||
/* the critical bit */
|
||||
{ FLAG, offsetof(private_sa_payload_t, critical) },
|
||||
/* 7 Bit reserved bits, nowhere stored */
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
/* Length of the whole SA payload*/
|
||||
{ PAYLOAD_LENGTH, offsetof(private_sa_payload_t, payload_length) },
|
||||
/* Proposals are stored in a proposal substructure,
|
||||
offset points to a linked_list_t pointer */
|
||||
{ PROPOSALS, offsetof(private_sa_payload_t, proposals) }
|
||||
};
|
||||
|
||||
/*
|
||||
1 2 3
|
||||
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 !C! RESERVED ! Payload Length !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! !
|
||||
~ <Proposals> ~
|
||||
! !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.verify.
|
||||
*/
|
||||
static status_t verify(private_sa_payload_t *this)
|
||||
{
|
||||
int proposal_number = 1;
|
||||
status_t status = SUCCESS;
|
||||
iterator_t *iterator;
|
||||
bool first = TRUE;
|
||||
|
||||
/* check proposal numbering */
|
||||
iterator = this->proposals->create_iterator(this->proposals,TRUE);
|
||||
|
||||
while(iterator->has_next(iterator))
|
||||
{
|
||||
proposal_substructure_t *current_proposal;
|
||||
iterator->current(iterator,(void **)¤t_proposal);
|
||||
if (current_proposal->get_proposal_number(current_proposal) > proposal_number)
|
||||
{
|
||||
if (first)
|
||||
{
|
||||
/* first number must be 1 */
|
||||
status = FAILED;
|
||||
break;
|
||||
}
|
||||
|
||||
if (current_proposal->get_proposal_number(current_proposal) != (proposal_number + 1))
|
||||
{
|
||||
/* must be only one more then previous proposal */
|
||||
status = FAILED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (current_proposal->get_proposal_number(current_proposal) < proposal_number)
|
||||
{
|
||||
/* must not be smaller then proceeding one */
|
||||
status = FAILED;
|
||||
break;
|
||||
}
|
||||
|
||||
status = current_proposal->payload_interface.verify(&(current_proposal->payload_interface));
|
||||
if (status != SUCCESS)
|
||||
{
|
||||
break;
|
||||
}
|
||||
first = FALSE;
|
||||
}
|
||||
|
||||
iterator->destroy(iterator);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.destroy and sa_payload_t.destroy.
|
||||
*/
|
||||
static status_t destroy(private_sa_payload_t *this)
|
||||
{
|
||||
/* all proposals are getting destroyed */
|
||||
while (this->proposals->get_count(this->proposals) > 0)
|
||||
{
|
||||
proposal_substructure_t *current_proposal;
|
||||
this->proposals->remove_last(this->proposals,(void **)¤t_proposal);
|
||||
current_proposal->destroy(current_proposal);
|
||||
}
|
||||
this->proposals->destroy(this->proposals);
|
||||
|
||||
free(this);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_encoding_rules.
|
||||
*/
|
||||
static void get_encoding_rules(private_sa_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
|
||||
{
|
||||
*rules = sa_payload_encodings;
|
||||
*rule_count = sizeof(sa_payload_encodings) / sizeof(encoding_rule_t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_type.
|
||||
*/
|
||||
static payload_type_t get_type(private_sa_payload_t *this)
|
||||
{
|
||||
return SECURITY_ASSOCIATION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_next_type.
|
||||
*/
|
||||
static payload_type_t get_next_type(private_sa_payload_t *this)
|
||||
{
|
||||
return (this->next_payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.set_next_type.
|
||||
*/
|
||||
static void set_next_type(private_sa_payload_t *this,payload_type_t type)
|
||||
{
|
||||
this->next_payload = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_length.
|
||||
*/
|
||||
static size_t get_length(private_sa_payload_t *this)
|
||||
{
|
||||
this->compute_length(this);
|
||||
return this->payload_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of sa_payload_t.create_proposal_substructure_iterator.
|
||||
*/
|
||||
static iterator_t *create_proposal_substructure_iterator (private_sa_payload_t *this,bool forward)
|
||||
{
|
||||
return this->proposals->create_iterator(this->proposals,forward);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of sa_payload_t.add_proposal_substructure.
|
||||
*/
|
||||
static void add_proposal_substructure (private_sa_payload_t *this,proposal_substructure_t *proposal)
|
||||
{
|
||||
status_t status;
|
||||
if (this->proposals->get_count(this->proposals) > 0)
|
||||
{
|
||||
proposal_substructure_t *last_proposal;
|
||||
status = this->proposals->get_last(this->proposals,(void **) &last_proposal);
|
||||
/* last transform is now not anymore last one */
|
||||
last_proposal->set_is_last_proposal(last_proposal,FALSE);
|
||||
}
|
||||
proposal->set_is_last_proposal(proposal,TRUE);
|
||||
|
||||
this->proposals->insert_last(this->proposals,(void *) proposal);
|
||||
this->compute_length(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of sa_payload_t.add_proposal.
|
||||
*/
|
||||
static void add_proposal(private_sa_payload_t *this, proposal_t *proposal)
|
||||
{
|
||||
proposal_substructure_t *substructure;
|
||||
protocol_id_t proto[2];
|
||||
u_int i;
|
||||
|
||||
/* build the substructures for every protocol */
|
||||
proposal->get_protocols(proposal, proto);
|
||||
for (i = 0; i<2; i++)
|
||||
{
|
||||
if (proto[i] != PROTO_NONE)
|
||||
{
|
||||
substructure = proposal_substructure_create_from_proposal(proposal, proto[i]);
|
||||
add_proposal_substructure(this, substructure);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of sa_payload_t.get_proposals.
|
||||
*/
|
||||
static linked_list_t *get_proposals(private_sa_payload_t *this)
|
||||
{
|
||||
int proposal_struct_number = 0;
|
||||
iterator_t *iterator;
|
||||
proposal_t *proposal;
|
||||
linked_list_t *proposal_list;
|
||||
|
||||
/* this list will hold our proposals */
|
||||
proposal_list = linked_list_create();
|
||||
|
||||
/* iterate over structures, one OR MORE structures will result in a proposal */
|
||||
iterator = this->proposals->create_iterator(this->proposals,TRUE);
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
proposal_substructure_t *proposal_struct;
|
||||
iterator->current(iterator,(void **)&(proposal_struct));
|
||||
|
||||
if (proposal_struct->get_proposal_number(proposal_struct) > proposal_struct_number)
|
||||
{
|
||||
/* here starts a new proposal, create a new one and add it to the list */
|
||||
proposal_struct_number = proposal_struct->get_proposal_number(proposal_struct);
|
||||
proposal = proposal_create(proposal_struct_number);
|
||||
proposal_list->insert_last(proposal_list, proposal);
|
||||
}
|
||||
/* proposal_substructure_t does the dirty work and builds up the proposal */
|
||||
proposal_struct->add_to_proposal(proposal_struct, proposal);
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
return proposal_list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of private_sa_payload_t.compute_length.
|
||||
*/
|
||||
static void compute_length (private_sa_payload_t *this)
|
||||
{
|
||||
iterator_t *iterator;
|
||||
size_t length = SA_PAYLOAD_HEADER_LENGTH;
|
||||
iterator = this->proposals->create_iterator(this->proposals,TRUE);
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
payload_t *current_proposal;
|
||||
iterator->current(iterator,(void **) ¤t_proposal);
|
||||
length += current_proposal->get_length(current_proposal);
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
this->payload_length = length;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
sa_payload_t *sa_payload_create()
|
||||
{
|
||||
private_sa_payload_t *this = malloc_thing(private_sa_payload_t);
|
||||
|
||||
/* public interface */
|
||||
this->public.payload_interface.verify = (status_t (*) (payload_t *))verify;
|
||||
this->public.payload_interface.get_encoding_rules = (void (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules;
|
||||
this->public.payload_interface.get_length = (size_t (*) (payload_t *)) get_length;
|
||||
this->public.payload_interface.get_next_type = (payload_type_t (*) (payload_t *)) get_next_type;
|
||||
this->public.payload_interface.set_next_type = (void (*) (payload_t *,payload_type_t)) set_next_type;
|
||||
this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_type;
|
||||
this->public.payload_interface.destroy = (void (*) (payload_t *))destroy;
|
||||
|
||||
/* public functions */
|
||||
this->public.create_proposal_substructure_iterator = (iterator_t* (*) (sa_payload_t *,bool)) create_proposal_substructure_iterator;
|
||||
this->public.add_proposal_substructure = (void (*) (sa_payload_t *,proposal_substructure_t *)) add_proposal_substructure;
|
||||
this->public.get_proposals = (linked_list_t* (*) (sa_payload_t *)) get_proposals;
|
||||
this->public.destroy = (void (*) (sa_payload_t *)) destroy;
|
||||
|
||||
/* private functions */
|
||||
this->compute_length = compute_length;
|
||||
|
||||
/* set default values of the fields */
|
||||
this->critical = FALSE;
|
||||
this->next_payload = NO_PAYLOAD;
|
||||
this->payload_length = SA_PAYLOAD_HEADER_LENGTH;
|
||||
|
||||
this->proposals = linked_list_create();
|
||||
return (&(this->public));
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
sa_payload_t *sa_payload_create_from_proposal_list(linked_list_t *proposals)
|
||||
{
|
||||
iterator_t *iterator;
|
||||
proposal_t *proposal;
|
||||
sa_payload_t *sa_payload = sa_payload_create();
|
||||
|
||||
/* add every payload from the list */
|
||||
iterator = proposals->create_iterator(proposals, TRUE);
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
iterator->current(iterator, (void**)&proposal);
|
||||
add_proposal((private_sa_payload_t*)sa_payload, proposal);
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
return sa_payload;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
sa_payload_t *sa_payload_create_from_proposal(proposal_t *proposal)
|
||||
{
|
||||
sa_payload_t *sa_payload = sa_payload_create();
|
||||
|
||||
add_proposal((private_sa_payload_t*)sa_payload, proposal);
|
||||
|
||||
return sa_payload;
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
/**
|
||||
* @file sa_payload.h
|
||||
*
|
||||
* @brief Interface of sa_payload_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef SA_PAYLOAD_H_
|
||||
#define SA_PAYLOAD_H_
|
||||
|
||||
#include <types.h>
|
||||
#include <encoding/payloads/payload.h>
|
||||
#include <encoding/payloads/proposal_substructure.h>
|
||||
#include <utils/linked_list.h>
|
||||
|
||||
/**
|
||||
* SA_PAYLOAD length in bytes without any proposal substructure.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
#define SA_PAYLOAD_HEADER_LENGTH 4
|
||||
|
||||
typedef struct sa_payload_t sa_payload_t;
|
||||
|
||||
/**
|
||||
* @brief Class representing an IKEv2-SA Payload.
|
||||
*
|
||||
* The SA Payload format is described in RFC section 3.3.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - sa_payload_create()
|
||||
* - sa_payload_create_from_ike_proposals()
|
||||
* - sa_payload_create_from_proposal()
|
||||
*
|
||||
* @todo Add support of algorithms without specified keylength in get_proposals and get_ike_proposals.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
struct sa_payload_t {
|
||||
/**
|
||||
* The payload_t interface.
|
||||
*/
|
||||
payload_t payload_interface;
|
||||
|
||||
/**
|
||||
* @brief Creates an iterator of stored proposal_substructure_t objects.
|
||||
*
|
||||
* @warning The created iterator has to get destroyed by the caller!
|
||||
*
|
||||
* @warning When deleting an proposal using this iterator,
|
||||
* the length of this transform substructure has to be refreshed
|
||||
* by calling get_length()!
|
||||
*
|
||||
* @param this calling sa_payload_t object
|
||||
* @param[in] forward iterator direction (TRUE: front to end)
|
||||
* @return created iterator_t object
|
||||
*/
|
||||
iterator_t *(*create_proposal_substructure_iterator) (sa_payload_t *this, bool forward);
|
||||
|
||||
/**
|
||||
* @brief Adds a proposal_substructure_t object to this object.
|
||||
*
|
||||
* @warning The added proposal_substructure_t object is
|
||||
* getting destroyed in destroy function of sa_payload_t.
|
||||
*
|
||||
* @param this calling sa_payload_t object
|
||||
* @param proposal proposal_substructure_t object to add
|
||||
*/
|
||||
void (*add_proposal_substructure) (sa_payload_t *this,proposal_substructure_t *proposal);
|
||||
|
||||
/**
|
||||
* @brief Gets the proposals in this payload as a list.
|
||||
*
|
||||
* @return a list containing proposal_t s
|
||||
*/
|
||||
linked_list_t *(*get_proposals) (sa_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Add a child proposal (AH/ESP) to the payload.
|
||||
*
|
||||
* @param proposal child proposal to add to the payload
|
||||
*/
|
||||
void (*add_proposal) (sa_payload_t *this, proposal_t *proposal);
|
||||
|
||||
/**
|
||||
* @brief Destroys an sa_payload_t object.
|
||||
*
|
||||
* @param this sa_payload_t object to destroy
|
||||
*/
|
||||
void (*destroy) (sa_payload_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Creates an empty sa_payload_t object
|
||||
*
|
||||
* @return created sa_payload_t object
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
sa_payload_t *sa_payload_create();
|
||||
|
||||
/**
|
||||
* @brief Creates a sa_payload_t object from a list of proposals.
|
||||
*
|
||||
* @param proposals list of proposals to build the payload from
|
||||
* @return sa_payload_t object
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
sa_payload_t *sa_payload_create_from_proposal_list(linked_list_t *proposals);
|
||||
|
||||
/**
|
||||
* @brief Creates a sa_payload_t object from a single proposal.
|
||||
*
|
||||
* This is only for convenience. Use sa_payload_create_from_proposal_list
|
||||
* if you want to add more than one proposal.
|
||||
*
|
||||
* @param proposal proposal from which the payload should be built.
|
||||
* @return sa_payload_t object
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
sa_payload_t *sa_payload_create_from_proposal(proposal_t *proposal);
|
||||
|
||||
#endif /*SA_PAYLOAD_H_*/
|
||||
@@ -0,0 +1,374 @@
|
||||
/**
|
||||
* @file traffic_selector_substructure.c
|
||||
*
|
||||
* @brief Interface of traffic_selector_substructure_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "traffic_selector_substructure.h"
|
||||
|
||||
#include <encoding/payloads/encodings.h>
|
||||
#include <utils/linked_list.h>
|
||||
|
||||
/**
|
||||
* String mappings for ts_type_t.
|
||||
*/
|
||||
mapping_t ts_type_m[] = {
|
||||
{TS_IPV4_ADDR_RANGE, "TS_IPV4_ADDR_RANGE"},
|
||||
{TS_IPV6_ADDR_RANGE, "TS_IPV6_ADDR_RANGE"},
|
||||
{MAPPING_END, NULL}
|
||||
};
|
||||
|
||||
|
||||
typedef struct private_traffic_selector_substructure_t private_traffic_selector_substructure_t;
|
||||
|
||||
/**
|
||||
* Private data of an traffic_selector_substructure_t object.
|
||||
*
|
||||
*/
|
||||
struct private_traffic_selector_substructure_t {
|
||||
/**
|
||||
* Public traffic_selector_substructure_t interface.
|
||||
*/
|
||||
traffic_selector_substructure_t public;
|
||||
|
||||
/**
|
||||
* Type of traffic selector.
|
||||
*/
|
||||
u_int8_t ts_type;
|
||||
|
||||
/**
|
||||
* IP Protocol ID.
|
||||
*/
|
||||
u_int8_t ip_protocol_id;
|
||||
|
||||
/**
|
||||
* Length of this payload.
|
||||
*/
|
||||
u_int16_t payload_length;
|
||||
|
||||
/**
|
||||
* Start port number.
|
||||
*/
|
||||
u_int16_t start_port;
|
||||
|
||||
/**
|
||||
* End port number.
|
||||
*/
|
||||
u_int16_t end_port;
|
||||
|
||||
/**
|
||||
* Starting address.
|
||||
*/
|
||||
chunk_t starting_address;
|
||||
|
||||
/**
|
||||
* Ending address.
|
||||
*/
|
||||
chunk_t ending_address;
|
||||
|
||||
/**
|
||||
* update length
|
||||
*/
|
||||
void (*compute_length) (private_traffic_selector_substructure_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Encoding rules to parse or generate a TS payload
|
||||
*
|
||||
* The defined offsets are the positions in a object of type
|
||||
* private_traffic_selector_substructure_t.
|
||||
*
|
||||
*/
|
||||
encoding_rule_t traffic_selector_substructure_encodings[] = {
|
||||
/* 1 Byte next ts type*/
|
||||
{ TS_TYPE, offsetof(private_traffic_selector_substructure_t, ts_type) },
|
||||
/* 1 Byte IP protocol id*/
|
||||
{ U_INT_8, offsetof(private_traffic_selector_substructure_t, ip_protocol_id) },
|
||||
/* Length of the whole payload*/
|
||||
{ PAYLOAD_LENGTH, offsetof(private_traffic_selector_substructure_t, payload_length) },
|
||||
/* 2 Byte start port*/
|
||||
{ U_INT_16, offsetof(private_traffic_selector_substructure_t, start_port) },
|
||||
/* 2 Byte end port*/
|
||||
{ U_INT_16, offsetof(private_traffic_selector_substructure_t, end_port) },
|
||||
/* starting address is either 4 or 16 byte */
|
||||
{ ADDRESS, offsetof(private_traffic_selector_substructure_t, starting_address) },
|
||||
/* ending address is either 4 or 16 byte */
|
||||
{ ADDRESS, offsetof(private_traffic_selector_substructure_t, ending_address) }
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
1 2 3
|
||||
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
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! TS Type !IP Protocol ID*| Selector Length |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Start Port* | End Port* |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! !
|
||||
~ Starting Address* ~
|
||||
! !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! !
|
||||
~ Ending Address* ~
|
||||
! !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.verify.
|
||||
*/
|
||||
static status_t verify(private_traffic_selector_substructure_t *this)
|
||||
{
|
||||
|
||||
if (this->start_port > this->end_port)
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
switch (this->ts_type)
|
||||
{
|
||||
case TS_IPV4_ADDR_RANGE:
|
||||
{
|
||||
if ((this->starting_address.len != 4) ||
|
||||
(this->ending_address.len != 4))
|
||||
{
|
||||
/* ipv4 address must be 4 bytes long */
|
||||
return FAILED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TS_IPV6_ADDR_RANGE:
|
||||
default:
|
||||
{
|
||||
/* not supported ts type */
|
||||
return FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of traffic_selector_substructure_t.get_encoding_rules.
|
||||
*/
|
||||
static void get_encoding_rules(private_traffic_selector_substructure_t *this, encoding_rule_t **rules, size_t *rule_count)
|
||||
{
|
||||
*rules = traffic_selector_substructure_encodings;
|
||||
*rule_count = sizeof(traffic_selector_substructure_encodings) / sizeof(encoding_rule_t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_type.
|
||||
*/
|
||||
static payload_type_t get_payload_type(private_traffic_selector_substructure_t *this)
|
||||
{
|
||||
return TRAFFIC_SELECTOR_SUBSTRUCTURE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_next_type.
|
||||
*/
|
||||
static payload_type_t get_next_type(private_traffic_selector_substructure_t *this)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.set_next_type.
|
||||
*/
|
||||
static void set_next_type(private_traffic_selector_substructure_t *this,payload_type_t type)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_length.
|
||||
*/
|
||||
static size_t get_length(private_traffic_selector_substructure_t *this)
|
||||
{
|
||||
return this->payload_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of traffic_selector_substructure_t.get_ts_type.
|
||||
*/
|
||||
static ts_type_t get_ts_type (private_traffic_selector_substructure_t *this)
|
||||
{
|
||||
return this->ts_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of traffic_selector_substructure_t.set_ts_type.
|
||||
*/
|
||||
static void set_ts_type (private_traffic_selector_substructure_t *this,ts_type_t ts_type)
|
||||
{
|
||||
this->ts_type = ts_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of traffic_selector_substructure_t.get_protocol_id.
|
||||
*/
|
||||
static u_int8_t get_protocol_id (private_traffic_selector_substructure_t *this)
|
||||
{
|
||||
return this->ip_protocol_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of traffic_selector_substructure_t.set_protocol_id.
|
||||
*/
|
||||
static void set_protocol_id (private_traffic_selector_substructure_t *this,u_int8_t protocol_id)
|
||||
{
|
||||
this->ip_protocol_id = protocol_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of traffic_selector_substructure_t.get_start_host.
|
||||
*/
|
||||
static host_t * get_start_host (private_traffic_selector_substructure_t *this)
|
||||
{
|
||||
return (host_create_from_chunk(AF_INET,this->starting_address, this->start_port));
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of traffic_selector_substructure_t.set_start_host.
|
||||
*/
|
||||
static void set_start_host (private_traffic_selector_substructure_t *this,host_t *start_host)
|
||||
{
|
||||
this->start_port = start_host->get_port(start_host);
|
||||
if (this->starting_address.ptr != NULL)
|
||||
{
|
||||
chunk_free(&(this->starting_address));
|
||||
}
|
||||
this->starting_address = start_host->get_address_as_chunk(start_host);
|
||||
this->compute_length(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of traffic_selector_substructure_t.get_end_host.
|
||||
*/
|
||||
static host_t *get_end_host (private_traffic_selector_substructure_t *this)
|
||||
{
|
||||
return (host_create_from_chunk(AF_INET,this->ending_address, this->end_port));
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of traffic_selector_substructure_t.set_end_host.
|
||||
*/
|
||||
static void set_end_host (private_traffic_selector_substructure_t *this,host_t *end_host)
|
||||
{
|
||||
this->end_port = end_host->get_port(end_host);
|
||||
if (this->ending_address.ptr != NULL)
|
||||
{
|
||||
chunk_free(&(this->ending_address));
|
||||
}
|
||||
this->ending_address = end_host->get_address_as_chunk(end_host);
|
||||
this->compute_length(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of traffic_selector_substructure_t.get_traffic_selector.
|
||||
*/
|
||||
static traffic_selector_t *get_traffic_selector(private_traffic_selector_substructure_t *this)
|
||||
{
|
||||
traffic_selector_t *ts;
|
||||
ts = traffic_selector_create_from_bytes(this->ip_protocol_id, this->ts_type,
|
||||
this->starting_address, this->start_port,
|
||||
this->ending_address, this->end_port);
|
||||
return ts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of private_ts_payload_t.compute_length
|
||||
*/
|
||||
void compute_length(private_traffic_selector_substructure_t *this)
|
||||
{
|
||||
this->payload_length = TRAFFIC_SELECTOR_HEADER_LENGTH + this->ending_address.len + this->starting_address.len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.destroy and traffic_selector_substructure_t.destroy.
|
||||
*/
|
||||
static void destroy(private_traffic_selector_substructure_t *this)
|
||||
{
|
||||
free(this->starting_address.ptr);
|
||||
free(this->ending_address.ptr);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
traffic_selector_substructure_t *traffic_selector_substructure_create()
|
||||
{
|
||||
private_traffic_selector_substructure_t *this = malloc_thing(private_traffic_selector_substructure_t);
|
||||
|
||||
/* interface functions */
|
||||
this->public.payload_interface.verify = (status_t (*) (payload_t *))verify;
|
||||
this->public.payload_interface.get_encoding_rules = (void (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules;
|
||||
this->public.payload_interface.get_length = (size_t (*) (payload_t *)) get_length;
|
||||
this->public.payload_interface.get_next_type = (payload_type_t (*) (payload_t *)) get_next_type;
|
||||
this->public.payload_interface.set_next_type = (void (*) (payload_t *,payload_type_t)) set_next_type;
|
||||
this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_payload_type;
|
||||
this->public.payload_interface.destroy = (void (*) (payload_t *))destroy;
|
||||
|
||||
/* public functions */
|
||||
this->public.destroy = (void (*) (traffic_selector_substructure_t *)) destroy;
|
||||
this->public.get_ts_type = (ts_type_t (*) (traffic_selector_substructure_t *)) get_ts_type;
|
||||
this->public.set_ts_type = (void (*) (traffic_selector_substructure_t *,ts_type_t)) set_ts_type;
|
||||
this->public.get_protocol_id = (u_int8_t (*) (traffic_selector_substructure_t *)) get_protocol_id;
|
||||
this->public.set_protocol_id = (void (*) (traffic_selector_substructure_t *,u_int8_t)) set_protocol_id;
|
||||
this->public.get_start_host = (host_t * (*) (traffic_selector_substructure_t *))get_start_host;
|
||||
this->public.set_start_host = (void (*) (traffic_selector_substructure_t *, host_t *))set_start_host;
|
||||
this->public.get_end_host = (host_t * (*) (traffic_selector_substructure_t *))get_end_host;
|
||||
this->public.set_end_host = (void (*) (traffic_selector_substructure_t *, host_t *))set_end_host;
|
||||
this->public.get_traffic_selector = (traffic_selector_t* (*)(traffic_selector_substructure_t*))get_traffic_selector;
|
||||
|
||||
/* private functions */
|
||||
this->compute_length = compute_length;
|
||||
|
||||
/* private variables */
|
||||
this->payload_length = TRAFFIC_SELECTOR_HEADER_LENGTH;
|
||||
this->start_port = 0;
|
||||
this->end_port = 0;
|
||||
this->starting_address = CHUNK_INITIALIZER;
|
||||
this->ending_address = CHUNK_INITIALIZER;
|
||||
this->ip_protocol_id = 0;
|
||||
/* must be set to be valid */
|
||||
this->ts_type = TS_IPV4_ADDR_RANGE;
|
||||
|
||||
return (&(this->public));
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
traffic_selector_substructure_t *traffic_selector_substructure_create_from_traffic_selector(traffic_selector_t *traffic_selector)
|
||||
{
|
||||
private_traffic_selector_substructure_t *this = (private_traffic_selector_substructure_t*)traffic_selector_substructure_create();
|
||||
this->ts_type = traffic_selector->get_type(traffic_selector);
|
||||
this->ip_protocol_id = traffic_selector->get_protocol(traffic_selector);
|
||||
this->start_port = traffic_selector->get_from_port(traffic_selector);
|
||||
this->end_port = traffic_selector->get_to_port(traffic_selector);
|
||||
this->starting_address = traffic_selector->get_from_address(traffic_selector);
|
||||
this->ending_address = traffic_selector->get_to_address(traffic_selector);
|
||||
|
||||
this->compute_length(this);
|
||||
|
||||
return &(this->public);
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
/**
|
||||
* @file traffic_selector_substructure.h
|
||||
*
|
||||
* @brief Interface of traffic_selector_substructure_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TRAFFIC_SELECTOR_SUBSTRUCTURE_H_
|
||||
#define TRAFFIC_SELECTOR_SUBSTRUCTURE_H_
|
||||
|
||||
#include <types.h>
|
||||
#include <encoding/payloads/payload.h>
|
||||
#include <utils/host.h>
|
||||
#include <config/traffic_selector.h>
|
||||
|
||||
/**
|
||||
* Length of a TRAFFIC SELECTOR SUBSTRUCTURE without start and end address.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
#define TRAFFIC_SELECTOR_HEADER_LENGTH 8
|
||||
|
||||
typedef struct traffic_selector_substructure_t traffic_selector_substructure_t;
|
||||
|
||||
/**
|
||||
* @brief Class representing an IKEv2 TRAFFIC SELECTOR.
|
||||
*
|
||||
* The TRAFFIC SELECTOR format is described in RFC section 3.13.1.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - traffic_selector_substructure_create()
|
||||
* - traffic_selector_substructure_create_from_traffic_selector()
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
struct traffic_selector_substructure_t {
|
||||
/**
|
||||
* The payload_t interface.
|
||||
*/
|
||||
payload_t payload_interface;
|
||||
|
||||
/**
|
||||
* @brief Get the type of Traffic selector.
|
||||
*
|
||||
* @param this calling traffic_selector_substructure_t object
|
||||
* @return type of traffic selector
|
||||
*
|
||||
*/
|
||||
ts_type_t (*get_ts_type) (traffic_selector_substructure_t *this);
|
||||
|
||||
/**
|
||||
* @brief Set the type of Traffic selector.
|
||||
*
|
||||
* @param this calling traffic_selector_substructure_t object
|
||||
* @param ts_type type of traffic selector
|
||||
*/
|
||||
void (*set_ts_type) (traffic_selector_substructure_t *this,ts_type_t ts_type);
|
||||
|
||||
/**
|
||||
* @brief Get the IP protocol ID of Traffic selector.
|
||||
*
|
||||
* @param this calling traffic_selector_substructure_t object
|
||||
* @return type of traffic selector
|
||||
*
|
||||
*/
|
||||
u_int8_t (*get_protocol_id) (traffic_selector_substructure_t *this);
|
||||
|
||||
/**
|
||||
* @brief Set the IP protocol ID of Traffic selector
|
||||
*
|
||||
* @param this calling traffic_selector_substructure_t object
|
||||
* @param protocol_id protocol ID of traffic selector
|
||||
*/
|
||||
void (*set_protocol_id) (traffic_selector_substructure_t *this,u_int8_t protocol_id);
|
||||
|
||||
/**
|
||||
* @brief Get the start port and address as host_t object.
|
||||
*
|
||||
* Returned host_t object has to get destroyed by the caller.
|
||||
*
|
||||
* @param this calling traffic_selector_substructure_t object
|
||||
* @return start host as host_t object
|
||||
*
|
||||
*/
|
||||
host_t *(*get_start_host) (traffic_selector_substructure_t *this);
|
||||
|
||||
/**
|
||||
* @brief Set the start port and address as host_t object.
|
||||
*
|
||||
* @param this calling traffic_selector_substructure_t object
|
||||
* @param start_host start host as host_t object
|
||||
*/
|
||||
void (*set_start_host) (traffic_selector_substructure_t *this,host_t *start_host);
|
||||
|
||||
/**
|
||||
* @brief Get the end port and address as host_t object.
|
||||
*
|
||||
* Returned host_t object has to get destroyed by the caller.
|
||||
*
|
||||
* @param this calling traffic_selector_substructure_t object
|
||||
* @return end host as host_t object
|
||||
*
|
||||
*/
|
||||
host_t *(*get_end_host) (traffic_selector_substructure_t *this);
|
||||
|
||||
/**
|
||||
* @brief Set the end port and address as host_t object.
|
||||
*
|
||||
* @param this calling traffic_selector_substructure_t object
|
||||
* @param end_host end host as host_t object
|
||||
*/
|
||||
void (*set_end_host) (traffic_selector_substructure_t *this,host_t *end_host);
|
||||
|
||||
/**
|
||||
* @brief Get a traffic_selector_t from this substructure.
|
||||
*
|
||||
* @warning traffic_selector_t must be destroyed after usage.
|
||||
*
|
||||
* @param this calling traffic_selector_substructure_t object
|
||||
* @return contained traffic_selector_t
|
||||
*/
|
||||
traffic_selector_t *(*get_traffic_selector) (traffic_selector_substructure_t *this);
|
||||
|
||||
/**
|
||||
* @brief Destroys an traffic_selector_substructure_t object.
|
||||
*
|
||||
* @param this traffic_selector_substructure_t object to destroy
|
||||
*/
|
||||
void (*destroy) (traffic_selector_substructure_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Creates an empty traffic_selector_substructure_t object.
|
||||
*
|
||||
* TS type is set to default TS_IPV4_ADDR_RANGE!
|
||||
*
|
||||
* @return traffic_selector_substructure_t object
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
traffic_selector_substructure_t *traffic_selector_substructure_create();
|
||||
|
||||
/**
|
||||
* @brief Creates an initialized traffif selector substructure using
|
||||
* the values from a traffic_selector_t.
|
||||
*
|
||||
* @param traffic_selector traffic_selector_t to use for initialization
|
||||
* @return traffic_selector_substructure_t object
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
traffic_selector_substructure_t *traffic_selector_substructure_create_from_traffic_selector(traffic_selector_t *traffic_selector);
|
||||
|
||||
|
||||
#endif /* /TRAFFIC_SELECTOR_SUBSTRUCTURE_H_ */
|
||||
@@ -0,0 +1,333 @@
|
||||
/**
|
||||
* @file transform_attribute.c
|
||||
*
|
||||
* @brief Implementation of transform_attribute_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "transform_attribute.h"
|
||||
|
||||
#include <encoding/payloads/encodings.h>
|
||||
#include <types.h>
|
||||
|
||||
typedef struct private_transform_attribute_t private_transform_attribute_t;
|
||||
|
||||
/**
|
||||
* Private data of an transform_attribute_t object.
|
||||
*
|
||||
*/
|
||||
struct private_transform_attribute_t {
|
||||
/**
|
||||
* Public transform_attribute_t interface.
|
||||
*/
|
||||
transform_attribute_t public;
|
||||
|
||||
/**
|
||||
* Attribute Format Flag.
|
||||
*
|
||||
* - TRUE means value is stored in attribute_length_or_value
|
||||
* - FALSE means value is stored in attribute_value
|
||||
*/
|
||||
bool attribute_format;
|
||||
|
||||
/**
|
||||
* Type of the attribute.
|
||||
*/
|
||||
u_int16_t attribute_type;
|
||||
|
||||
/**
|
||||
* Attribute Length if attribute_format is 0, attribute Value otherwise.
|
||||
*/
|
||||
u_int16_t attribute_length_or_value;
|
||||
|
||||
/**
|
||||
* Attribute value as chunk if attribute_format is 0 (FALSE).
|
||||
*/
|
||||
chunk_t attribute_value;
|
||||
};
|
||||
|
||||
/**
|
||||
* String mappings for transform_attribute_type_t.
|
||||
*/
|
||||
mapping_t transform_attribute_type_m[] = {
|
||||
{ATTRIBUTE_UNDEFINED, "ATTRIBUTE_UNDEFINED"},
|
||||
{KEY_LENGTH, "KEY_LENGTH"},
|
||||
{MAPPING_END, NULL}
|
||||
};
|
||||
|
||||
/**
|
||||
* Encoding rules to parse or generate a Transform attribute.
|
||||
*
|
||||
* The defined offsets are the positions in a object of type
|
||||
* private_transform_attribute_t.
|
||||
*
|
||||
*/
|
||||
encoding_rule_t transform_attribute_encodings[] = {
|
||||
/* Flag defining the format of this payload */
|
||||
{ ATTRIBUTE_FORMAT, offsetof(private_transform_attribute_t, attribute_format) },
|
||||
/* type of the attribute as 15 bit unsigned integer */
|
||||
{ ATTRIBUTE_TYPE, offsetof(private_transform_attribute_t, attribute_type) },
|
||||
/* Length or value, depending on the attribute format flag */
|
||||
{ ATTRIBUTE_LENGTH_OR_VALUE, offsetof(private_transform_attribute_t, attribute_length_or_value) },
|
||||
/* Value of attribute if attribute format flag is zero */
|
||||
{ ATTRIBUTE_VALUE, offsetof(private_transform_attribute_t, attribute_value) }
|
||||
};
|
||||
|
||||
/*
|
||||
1 2 3
|
||||
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 !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.verify.
|
||||
*/
|
||||
static status_t verify(private_transform_attribute_t *this)
|
||||
{
|
||||
if (this->attribute_type != KEY_LENGTH)
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_encoding_rules.
|
||||
*/
|
||||
static void get_encoding_rules(private_transform_attribute_t *this, encoding_rule_t **rules, size_t *rule_count)
|
||||
{
|
||||
*rules = transform_attribute_encodings;
|
||||
*rule_count = sizeof(transform_attribute_encodings) / sizeof(encoding_rule_t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_type.
|
||||
*/
|
||||
static payload_type_t get_type(private_transform_attribute_t *this)
|
||||
{
|
||||
return TRANSFORM_ATTRIBUTE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_next_type.
|
||||
*/
|
||||
static payload_type_t get_next_type(private_transform_attribute_t *this)
|
||||
{
|
||||
return (NO_PAYLOAD);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.set_next_type.
|
||||
*/
|
||||
static void set_next_type(private_transform_attribute_t *this,payload_type_t type)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of transform_attribute_t.get_length.
|
||||
*/
|
||||
static size_t get_length(private_transform_attribute_t *this)
|
||||
{
|
||||
if (this->attribute_format == TRUE)
|
||||
{
|
||||
/*Attribute size is only 4 byte */
|
||||
return 4;
|
||||
}
|
||||
return (this->attribute_length_or_value + 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of transform_attribute_t.set_value_chunk.
|
||||
*/
|
||||
static void set_value_chunk(private_transform_attribute_t *this, chunk_t value)
|
||||
{
|
||||
if (this->attribute_value.ptr != NULL)
|
||||
{
|
||||
/* free existing value */
|
||||
free(this->attribute_value.ptr);
|
||||
this->attribute_value.ptr = NULL;
|
||||
this->attribute_value.len = 0;
|
||||
|
||||
}
|
||||
|
||||
if (value.len > 2)
|
||||
{
|
||||
this->attribute_value.ptr = clalloc(value.ptr,value.len);
|
||||
this->attribute_value.len = value.len;
|
||||
this->attribute_length_or_value = value.len;
|
||||
/* attribute has not a fixed length */
|
||||
this->attribute_format = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(&(this->attribute_length_or_value),value.ptr,value.len);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of transform_attribute_t.set_value.
|
||||
*/
|
||||
static void set_value(private_transform_attribute_t *this, u_int16_t value)
|
||||
{
|
||||
if (this->attribute_value.ptr != NULL)
|
||||
{
|
||||
/* free existing value */
|
||||
free(this->attribute_value.ptr);
|
||||
this->attribute_value.ptr = NULL;
|
||||
this->attribute_value.len = 0;
|
||||
|
||||
}
|
||||
this->attribute_length_or_value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of transform_attribute_t.get_value_chunk.
|
||||
*/
|
||||
static chunk_t get_value_chunk (private_transform_attribute_t *this)
|
||||
{
|
||||
chunk_t value;
|
||||
|
||||
if (this->attribute_format == FALSE)
|
||||
{
|
||||
value.ptr = this->attribute_value.ptr;
|
||||
value.len = this->attribute_value.len;
|
||||
}
|
||||
else
|
||||
{
|
||||
value.ptr = (void *) &(this->attribute_length_or_value);
|
||||
value.len = 2;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of transform_attribute_t.get_value.
|
||||
*/
|
||||
static u_int16_t get_value (private_transform_attribute_t *this)
|
||||
{
|
||||
return this->attribute_length_or_value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of transform_attribute_t.set_attribute_type.
|
||||
*/
|
||||
static void set_attribute_type (private_transform_attribute_t *this, u_int16_t type)
|
||||
{
|
||||
this->attribute_type = type & 0x7FFF;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of transform_attribute_t.get_attribute_type.
|
||||
*/
|
||||
static u_int16_t get_attribute_type (private_transform_attribute_t *this)
|
||||
{
|
||||
return this->attribute_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of transform_attribute_t.clone.
|
||||
*/
|
||||
static transform_attribute_t * clone(private_transform_attribute_t *this)
|
||||
{
|
||||
private_transform_attribute_t *new_clone;
|
||||
|
||||
new_clone = (private_transform_attribute_t *) transform_attribute_create();
|
||||
|
||||
new_clone->attribute_format = this->attribute_format;
|
||||
new_clone->attribute_type = this->attribute_type;
|
||||
new_clone->attribute_length_or_value = this->attribute_length_or_value;
|
||||
|
||||
if (!new_clone->attribute_format)
|
||||
{
|
||||
new_clone->attribute_value.ptr = clalloc(this->attribute_value.ptr,this->attribute_value.len);
|
||||
new_clone->attribute_value.len = this->attribute_value.len;
|
||||
}
|
||||
|
||||
return (transform_attribute_t *) new_clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of transform_attribute_t.destroy and payload_t.destroy.
|
||||
*/
|
||||
static void destroy(private_transform_attribute_t *this)
|
||||
{
|
||||
if (this->attribute_value.ptr != NULL)
|
||||
{
|
||||
free(this->attribute_value.ptr);
|
||||
}
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
transform_attribute_t *transform_attribute_create()
|
||||
{
|
||||
private_transform_attribute_t *this = malloc_thing(private_transform_attribute_t);
|
||||
|
||||
/* payload interface */
|
||||
this->public.payload_interface.verify = (status_t (*) (payload_t *))verify;
|
||||
this->public.payload_interface.get_encoding_rules = (void (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules;
|
||||
this->public.payload_interface.get_length = (size_t (*) (payload_t *)) get_length;
|
||||
this->public.payload_interface.get_next_type = (payload_type_t (*) (payload_t *)) get_next_type;
|
||||
this->public.payload_interface.set_next_type = (void (*) (payload_t *,payload_type_t)) set_next_type;
|
||||
this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_type;
|
||||
this->public.payload_interface.destroy = (void (*) (payload_t *))destroy;
|
||||
|
||||
/* public functions */
|
||||
this->public.set_value_chunk = (void (*) (transform_attribute_t *,chunk_t)) set_value_chunk;
|
||||
this->public.set_value = (void (*) (transform_attribute_t *,u_int16_t)) set_value;
|
||||
this->public.get_value_chunk = (chunk_t (*) (transform_attribute_t *)) get_value_chunk;
|
||||
this->public.get_value = (u_int16_t (*) (transform_attribute_t *)) get_value;
|
||||
this->public.set_attribute_type = (void (*) (transform_attribute_t *,u_int16_t type)) set_attribute_type;
|
||||
this->public.get_attribute_type = (u_int16_t (*) (transform_attribute_t *)) get_attribute_type;
|
||||
this->public.clone = (transform_attribute_t * (*) (transform_attribute_t *)) clone;
|
||||
this->public.destroy = (void (*) (transform_attribute_t *)) destroy;
|
||||
|
||||
/* set default values of the fields */
|
||||
this->attribute_format = TRUE;
|
||||
this->attribute_type = 0;
|
||||
this->attribute_length_or_value = 0;
|
||||
this->attribute_value.ptr = NULL;
|
||||
this->attribute_value.len = 0;
|
||||
|
||||
return (&(this->public));
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
transform_attribute_t *transform_attribute_create_key_length(u_int16_t key_length)
|
||||
{
|
||||
transform_attribute_t *attribute = transform_attribute_create();
|
||||
attribute->set_attribute_type(attribute,KEY_LENGTH);
|
||||
attribute->set_value(attribute,key_length);
|
||||
return attribute;
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* @file transform_attribute.h
|
||||
*
|
||||
* @brief Interface of transform_attribute_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef TRANSFORM_ATTRIBUTE_H_
|
||||
#define TRANSFORM_ATTRIBUTE_H_
|
||||
|
||||
#include <types.h>
|
||||
#include <encoding/payloads/payload.h>
|
||||
|
||||
|
||||
typedef enum transform_attribute_type_t transform_attribute_type_t;
|
||||
|
||||
/**
|
||||
* Type of the attribute, as in IKEv2 RFC 3.3.5.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
enum transform_attribute_type_t {
|
||||
ATTRIBUTE_UNDEFINED = 16384,
|
||||
KEY_LENGTH = 14
|
||||
};
|
||||
|
||||
/**
|
||||
* String mappings for transform_attribute_type_t.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
extern mapping_t transform_attribute_type_m[];
|
||||
|
||||
typedef struct transform_attribute_t transform_attribute_t;
|
||||
|
||||
/**
|
||||
* @brief Class representing an IKEv2- TRANSFORM Attribute.
|
||||
*
|
||||
* The TRANSFORM ATTRIBUTE format is described in RFC section 3.3.5.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
struct transform_attribute_t {
|
||||
/**
|
||||
* The payload_t interface.
|
||||
*/
|
||||
payload_t payload_interface;
|
||||
|
||||
/**
|
||||
* @brief Returns the currently set value of the attribute.
|
||||
*
|
||||
* @warning Returned data are not copied.
|
||||
*
|
||||
* @param this calling transform_attribute_t object
|
||||
* @return chunk_t pointing to the value
|
||||
*/
|
||||
chunk_t (*get_value_chunk) (transform_attribute_t *this);
|
||||
|
||||
/**
|
||||
* @brief Returns the currently set value of the attribute.
|
||||
*
|
||||
* @warning Returned data are not copied.
|
||||
*
|
||||
* @param this calling transform_attribute_t object
|
||||
* @return value
|
||||
*/
|
||||
u_int16_t (*get_value) (transform_attribute_t *this);
|
||||
|
||||
/**
|
||||
* @brief Sets the value of the attribute.
|
||||
*
|
||||
* @warning Value is getting copied.
|
||||
*
|
||||
* @param this calling transform_attribute_t object
|
||||
* @param value chunk_t pointing to the value to set
|
||||
*/
|
||||
void (*set_value_chunk) (transform_attribute_t *this, chunk_t value);
|
||||
|
||||
/**
|
||||
* @brief Sets the value of the attribute.
|
||||
*
|
||||
* @param this calling transform_attribute_t object
|
||||
* @param value value to set
|
||||
*/
|
||||
void (*set_value) (transform_attribute_t *this, u_int16_t value);
|
||||
|
||||
/**
|
||||
* @brief Sets the type of the attribute.
|
||||
*
|
||||
* @param this calling transform_attribute_t object
|
||||
* @param type type to set (most significant bit is set to zero)
|
||||
*/
|
||||
void (*set_attribute_type) (transform_attribute_t *this, u_int16_t type);
|
||||
|
||||
/**
|
||||
* @brief get the type of the attribute.
|
||||
*
|
||||
* @param this calling transform_attribute_t object
|
||||
* @return type of the value
|
||||
*/
|
||||
u_int16_t (*get_attribute_type) (transform_attribute_t *this);
|
||||
|
||||
/**
|
||||
* @brief Clones an transform_attribute_t object.
|
||||
*
|
||||
* @param this transform_attribute_t object to clone
|
||||
* @return cloned transform_attribute_t object
|
||||
*/
|
||||
transform_attribute_t * (*clone) (transform_attribute_t *this);
|
||||
|
||||
/**
|
||||
* @brief Destroys an transform_attribute_t object.
|
||||
*
|
||||
* @param this transform_attribute_t object to destroy
|
||||
*/
|
||||
void (*destroy) (transform_attribute_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Creates an empty transform_attribute_t object.
|
||||
*
|
||||
* @return transform_attribute_t object
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
transform_attribute_t *transform_attribute_create();
|
||||
|
||||
/**
|
||||
* @brief Creates an transform_attribute_t of type KEY_LENGTH.
|
||||
*
|
||||
* @param key_length key length in bytes
|
||||
* @return transform_attribute_t object
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
transform_attribute_t *transform_attribute_create_key_length(u_int16_t key_length);
|
||||
|
||||
|
||||
#endif /*TRANSFORM_ATTRIBUTE_H_*/
|
||||
@@ -0,0 +1,485 @@
|
||||
/**
|
||||
* @file transform_substructure.h
|
||||
*
|
||||
* @brief Implementation of transform_substructure_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "transform_substructure.h"
|
||||
|
||||
#include <encoding/payloads/transform_attribute.h>
|
||||
#include <encoding/payloads/encodings.h>
|
||||
#include <types.h>
|
||||
#include <utils/linked_list.h>
|
||||
|
||||
|
||||
typedef struct private_transform_substructure_t private_transform_substructure_t;
|
||||
|
||||
/**
|
||||
* Private data of an transform_substructure_t object.
|
||||
*
|
||||
*/
|
||||
struct private_transform_substructure_t {
|
||||
/**
|
||||
* Public transform_substructure_t interface.
|
||||
*/
|
||||
transform_substructure_t public;
|
||||
|
||||
/**
|
||||
* Next payload type.
|
||||
*/
|
||||
u_int8_t next_payload;
|
||||
|
||||
|
||||
/**
|
||||
* Length of this payload.
|
||||
*/
|
||||
u_int16_t transform_length;
|
||||
|
||||
|
||||
/**
|
||||
* Type of the transform.
|
||||
*/
|
||||
u_int8_t transform_type;
|
||||
|
||||
/**
|
||||
* Transform ID.
|
||||
*/
|
||||
u_int16_t transform_id;
|
||||
|
||||
/**
|
||||
* Transforms Attributes are stored in a linked_list_t.
|
||||
*/
|
||||
linked_list_t *attributes;
|
||||
|
||||
/**
|
||||
* @brief Computes the length of this substructure.
|
||||
*
|
||||
* @param this calling private_transform_substructure_t object
|
||||
*/
|
||||
void (*compute_length) (private_transform_substructure_t *this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Encoding rules to parse or generate a Transform substructure.
|
||||
*
|
||||
* The defined offsets are the positions in a object of type
|
||||
* private_transform_substructure_t.
|
||||
*
|
||||
*/
|
||||
encoding_rule_t transform_substructure_encodings[] = {
|
||||
/* 1 Byte next payload type, stored in the field next_payload */
|
||||
{ U_INT_8, offsetof(private_transform_substructure_t, next_payload) },
|
||||
/* Reserved Byte is skipped */
|
||||
{ RESERVED_BYTE, 0 },
|
||||
/* Length of the whole transform substructure*/
|
||||
{ PAYLOAD_LENGTH, offsetof(private_transform_substructure_t, transform_length) },
|
||||
/* transform type is a number of 8 bit */
|
||||
{ U_INT_8, offsetof(private_transform_substructure_t, transform_type) },
|
||||
/* Reserved Byte is skipped */
|
||||
{ RESERVED_BYTE, 0 },
|
||||
/* tranform ID is a number of 8 bit */
|
||||
{ U_INT_16, offsetof(private_transform_substructure_t, transform_id) },
|
||||
/* Attributes are stored in a transform attribute,
|
||||
offset points to a linked_list_t pointer */
|
||||
{ TRANSFORM_ATTRIBUTES, offsetof(private_transform_substructure_t, attributes) }
|
||||
};
|
||||
|
||||
/*
|
||||
1 2 3
|
||||
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
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! 0 (last) or 3 ! RESERVED ! Transform Length !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
!Transform Type ! RESERVED ! Transform ID !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! !
|
||||
~ Transform Attributes ~
|
||||
! !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.verify.
|
||||
*/
|
||||
static status_t verify(private_transform_substructure_t *this)
|
||||
{
|
||||
status_t status = SUCCESS;
|
||||
iterator_t *iterator;
|
||||
|
||||
if ((this->next_payload != NO_PAYLOAD) && (this->next_payload != 3))
|
||||
{
|
||||
/* must be 0 or 3 */
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
switch (this->transform_type)
|
||||
{
|
||||
case ENCRYPTION_ALGORITHM:
|
||||
{
|
||||
if ((this->transform_id < ENCR_DES_IV64) || (this->transform_id > ENCR_AES_CTR))
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PSEUDO_RANDOM_FUNCTION:
|
||||
{
|
||||
if ((this->transform_id < PRF_HMAC_MD5) || (this->transform_id > PRF_AES128_CBC))
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case INTEGRITY_ALGORITHM:
|
||||
{
|
||||
if ((this->transform_id < AUTH_HMAC_MD5_96) || (this->transform_id > AUTH_AES_XCBC_96))
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DIFFIE_HELLMAN_GROUP:
|
||||
{
|
||||
switch (this->transform_id)
|
||||
{
|
||||
case MODP_768_BIT:
|
||||
case MODP_1024_BIT:
|
||||
case MODP_1536_BIT:
|
||||
case MODP_2048_BIT:
|
||||
case MODP_3072_BIT:
|
||||
case MODP_4096_BIT:
|
||||
case MODP_6144_BIT:
|
||||
case MODP_8192_BIT:
|
||||
{
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
case EXTENDED_SEQUENCE_NUMBERS:
|
||||
{
|
||||
if ((this->transform_id != NO_EXT_SEQ_NUMBERS) && (this->transform_id != EXT_SEQ_NUMBERS))
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
/* not a supported transform type! */
|
||||
return FAILED;
|
||||
}
|
||||
}
|
||||
iterator = this->attributes->create_iterator(this->attributes,TRUE);
|
||||
|
||||
while(iterator->has_next(iterator))
|
||||
{
|
||||
payload_t *current_attributes;
|
||||
iterator->current(iterator,(void **)¤t_attributes);
|
||||
|
||||
status = current_attributes->verify(current_attributes);
|
||||
if (status != SUCCESS)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
iterator->destroy(iterator);
|
||||
|
||||
|
||||
/* proposal number is checked in SA payload */
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_encoding_rules.
|
||||
*/
|
||||
static void get_encoding_rules(private_transform_substructure_t *this, encoding_rule_t **rules, size_t *rule_count)
|
||||
{
|
||||
*rules = transform_substructure_encodings;
|
||||
*rule_count = sizeof(transform_substructure_encodings) / sizeof(encoding_rule_t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_type.
|
||||
*/
|
||||
static payload_type_t get_type(private_transform_substructure_t *this)
|
||||
{
|
||||
return TRANSFORM_SUBSTRUCTURE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_next_type.
|
||||
*/
|
||||
static payload_type_t get_next_type(private_transform_substructure_t *this)
|
||||
{
|
||||
return (this->next_payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_length.
|
||||
*/
|
||||
static size_t get_length(private_transform_substructure_t *this)
|
||||
{
|
||||
this->compute_length(this);
|
||||
|
||||
return this->transform_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of transform_substructure_t.create_transform_attribute_iterator.
|
||||
*/
|
||||
static iterator_t *create_transform_attribute_iterator (private_transform_substructure_t *this,bool forward)
|
||||
{
|
||||
return this->attributes->create_iterator(this->attributes,forward);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of transform_substructure_t.add_transform_attribute.
|
||||
*/
|
||||
static void add_transform_attribute (private_transform_substructure_t *this,transform_attribute_t *attribute)
|
||||
{
|
||||
this->attributes->insert_last(this->attributes,(void *) attribute);
|
||||
this->compute_length(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of transform_substructure_t.set_is_last_transform.
|
||||
*/
|
||||
static void set_is_last_transform (private_transform_substructure_t *this, bool is_last)
|
||||
{
|
||||
this->next_payload = (is_last) ? 0: TRANSFORM_TYPE_VALUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of transform_substructure_t.get_is_last_transform.
|
||||
*/
|
||||
static bool get_is_last_transform (private_transform_substructure_t *this)
|
||||
{
|
||||
return ((this->next_payload == TRANSFORM_TYPE_VALUE) ? FALSE : TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.set_next_type.
|
||||
*/
|
||||
static void set_next_type(private_transform_substructure_t *this,payload_type_t type)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of transform_substructure_t.set_transform_type.
|
||||
*/
|
||||
static void set_transform_type (private_transform_substructure_t *this,u_int8_t type)
|
||||
{
|
||||
this->transform_type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of transform_substructure_t.get_transform_type.
|
||||
*/
|
||||
static u_int8_t get_transform_type (private_transform_substructure_t *this)
|
||||
{
|
||||
return this->transform_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of transform_substructure_t.set_transform_id.
|
||||
*/
|
||||
static void set_transform_id (private_transform_substructure_t *this,u_int16_t id)
|
||||
{
|
||||
this->transform_id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of transform_substructure_t.get_transform_id.
|
||||
*/
|
||||
static u_int16_t get_transform_id (private_transform_substructure_t *this)
|
||||
{
|
||||
return this->transform_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of private_transform_substructure_t.compute_length.
|
||||
*/
|
||||
static void compute_length (private_transform_substructure_t *this)
|
||||
{
|
||||
iterator_t *iterator;
|
||||
size_t length = TRANSFORM_SUBSTRUCTURE_HEADER_LENGTH;
|
||||
iterator = this->attributes->create_iterator(this->attributes,TRUE);
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
payload_t * current_attribute;
|
||||
iterator->current(iterator,(void **) ¤t_attribute);
|
||||
length += current_attribute->get_length(current_attribute);
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
this->transform_length = length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of transform_substructure_t.clone.
|
||||
*/
|
||||
static transform_substructure_t *clone(private_transform_substructure_t *this)
|
||||
{
|
||||
private_transform_substructure_t *new_clone;
|
||||
iterator_t *attributes;
|
||||
|
||||
new_clone = (private_transform_substructure_t *) transform_substructure_create();
|
||||
|
||||
new_clone->next_payload = this->next_payload;
|
||||
new_clone->transform_type = this->transform_type;
|
||||
new_clone->transform_id = this->transform_id;
|
||||
|
||||
attributes = this->attributes->create_iterator(this->attributes,FALSE);
|
||||
|
||||
while (attributes->has_next(attributes))
|
||||
{
|
||||
transform_attribute_t *current_attribute;
|
||||
transform_attribute_t *current_attribute_clone;
|
||||
attributes->current(attributes,(void **) ¤t_attribute);
|
||||
|
||||
current_attribute_clone = current_attribute->clone(current_attribute);
|
||||
|
||||
new_clone->public.add_transform_attribute(&(new_clone->public),current_attribute_clone);
|
||||
}
|
||||
|
||||
attributes->destroy(attributes);
|
||||
|
||||
return &(new_clone->public);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of transform_substructure_t.get_key_length.
|
||||
*/
|
||||
static status_t get_key_length(private_transform_substructure_t *this, u_int16_t *key_length)
|
||||
{
|
||||
iterator_t *attributes;
|
||||
|
||||
attributes = this->attributes->create_iterator(this->attributes,TRUE);
|
||||
|
||||
while (attributes->has_next(attributes))
|
||||
{
|
||||
transform_attribute_t *current_attribute;
|
||||
attributes->current(attributes,(void **) ¤t_attribute);
|
||||
|
||||
if (current_attribute->get_attribute_type(current_attribute) == KEY_LENGTH)
|
||||
{
|
||||
*key_length = current_attribute->get_value(current_attribute);
|
||||
attributes->destroy(attributes);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
}
|
||||
attributes->destroy(attributes);
|
||||
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of transform_substructure_t.destroy and payload_t.destroy.
|
||||
*/
|
||||
static void destroy(private_transform_substructure_t *this)
|
||||
{
|
||||
/* all proposals are getting destroyed */
|
||||
while (this->attributes->get_count(this->attributes) > 0)
|
||||
{
|
||||
transform_attribute_t *current_attribute;
|
||||
this->attributes->remove_last(this->attributes,(void **)¤t_attribute);
|
||||
current_attribute->destroy(current_attribute);
|
||||
}
|
||||
this->attributes->destroy(this->attributes);
|
||||
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
transform_substructure_t *transform_substructure_create()
|
||||
{
|
||||
private_transform_substructure_t *this = malloc_thing(private_transform_substructure_t);
|
||||
|
||||
/* payload interface */
|
||||
this->public.payload_interface.verify = (status_t (*) (payload_t *))verify;
|
||||
this->public.payload_interface.get_encoding_rules = (void (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules;
|
||||
this->public.payload_interface.get_length = (size_t (*) (payload_t *)) get_length;
|
||||
this->public.payload_interface.get_next_type = (payload_type_t (*) (payload_t *)) get_next_type;
|
||||
this->public.payload_interface.set_next_type = (void (*) (payload_t *,payload_type_t)) set_next_type;
|
||||
this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_type;
|
||||
this->public.payload_interface.destroy = (void (*) (payload_t *))destroy;
|
||||
|
||||
/* public functions */
|
||||
this->public.create_transform_attribute_iterator = (iterator_t * (*) (transform_substructure_t *,bool)) create_transform_attribute_iterator;
|
||||
this->public.add_transform_attribute = (void (*) (transform_substructure_t *,transform_attribute_t *)) add_transform_attribute;
|
||||
this->public.set_is_last_transform = (void (*) (transform_substructure_t *,bool)) set_is_last_transform;
|
||||
this->public.get_is_last_transform = (bool (*) (transform_substructure_t *)) get_is_last_transform;
|
||||
this->public.set_transform_type = (void (*) (transform_substructure_t *,u_int8_t)) set_transform_type;
|
||||
this->public.get_transform_type = (u_int8_t (*) (transform_substructure_t *)) get_transform_type;
|
||||
this->public.set_transform_id = (void (*) (transform_substructure_t *,u_int16_t)) set_transform_id;
|
||||
this->public.get_transform_id = (u_int16_t (*) (transform_substructure_t *)) get_transform_id;
|
||||
this->public.get_key_length = (status_t (*) (transform_substructure_t *,u_int16_t *)) get_key_length;
|
||||
this->public.clone = (transform_substructure_t* (*) (transform_substructure_t *)) clone;
|
||||
this->public.destroy = (void (*) (transform_substructure_t *)) destroy;
|
||||
|
||||
/* private functions */
|
||||
this->compute_length = compute_length;
|
||||
|
||||
/* set default values of the fields */
|
||||
this->next_payload = NO_PAYLOAD;
|
||||
this->transform_length = TRANSFORM_SUBSTRUCTURE_HEADER_LENGTH;
|
||||
this->transform_id = 0;
|
||||
this->transform_type = 0;
|
||||
this->attributes = linked_list_create();
|
||||
|
||||
return (&(this->public));
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
transform_substructure_t *transform_substructure_create_type(transform_type_t transform_type, u_int16_t transform_id, u_int16_t key_length)
|
||||
{
|
||||
transform_substructure_t *transform = transform_substructure_create();
|
||||
|
||||
transform->set_transform_type(transform,transform_type);
|
||||
transform->set_transform_id(transform,transform_id);
|
||||
|
||||
/* a keylength attribute is only created for AES encryption */
|
||||
if (transform_type == ENCRYPTION_ALGORITHM &&
|
||||
transform_id == ENCR_AES_CBC)
|
||||
{
|
||||
transform_attribute_t *attribute = transform_attribute_create_key_length(key_length);
|
||||
transform->add_transform_attribute(transform,attribute);
|
||||
}
|
||||
|
||||
return transform;
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
/**
|
||||
* @file transform_substructure.h
|
||||
*
|
||||
* @brief Interface of transform_substructure_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef TRANSFORM_SUBSTRUCTURE_H_
|
||||
#define TRANSFORM_SUBSTRUCTURE_H_
|
||||
|
||||
#include <types.h>
|
||||
#include <definitions.h>
|
||||
#include <encoding/payloads/payload.h>
|
||||
#include <encoding/payloads/transform_attribute.h>
|
||||
#include <utils/linked_list.h>
|
||||
#include <crypto/diffie_hellman.h>
|
||||
#include <crypto/signers/signer.h>
|
||||
#include <crypto/prfs/prf.h>
|
||||
#include <crypto/crypters/crypter.h>
|
||||
#include <config/proposal.h>
|
||||
|
||||
|
||||
/**
|
||||
* IKEv1 Value for a transform payload.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
#define TRANSFORM_TYPE_VALUE 3
|
||||
|
||||
/**
|
||||
* Length of the transform substructure header in bytes.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
#define TRANSFORM_SUBSTRUCTURE_HEADER_LENGTH 8
|
||||
|
||||
|
||||
typedef struct transform_substructure_t transform_substructure_t;
|
||||
|
||||
/**
|
||||
* @brief Class representing an IKEv2- TRANSFORM SUBSTRUCTURE.
|
||||
*
|
||||
* The TRANSFORM SUBSTRUCTURE format is described in RFC section 3.3.2.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
struct transform_substructure_t {
|
||||
/**
|
||||
* The payload_t interface.
|
||||
*/
|
||||
payload_t payload_interface;
|
||||
|
||||
/**
|
||||
* @brief Creates an iterator of stored transform_attribute_t objects.
|
||||
*
|
||||
* @warning The created iterator has to get destroyed by the caller!
|
||||
*
|
||||
* @warning When deleting an transform attribute using this iterator,
|
||||
* the length of this transform substructure has to be refreshed
|
||||
* by calling get_length()!
|
||||
*
|
||||
* @param this calling transform_substructure_t object
|
||||
* @param[in] forward iterator direction (TRUE: front to end)
|
||||
* @return created iterator_t object.
|
||||
*/
|
||||
iterator_t * (*create_transform_attribute_iterator) (transform_substructure_t *this, bool forward);
|
||||
|
||||
/**
|
||||
* @brief Adds a transform_attribute_t object to this object.
|
||||
*
|
||||
* @warning The added proposal_substructure_t object is
|
||||
* getting destroyed in destroy function of transform_substructure_t.
|
||||
*
|
||||
* @param this calling transform_substructure_t object
|
||||
* @param proposal transform_attribute_t object to add
|
||||
*/
|
||||
void (*add_transform_attribute) (transform_substructure_t *this,transform_attribute_t *attribute);
|
||||
|
||||
/**
|
||||
* @brief Sets the next_payload field of this substructure
|
||||
*
|
||||
* If this is the last transform, next payload field is set to 0,
|
||||
* otherwise to 3
|
||||
*
|
||||
* @param this calling transform_substructure_t object
|
||||
* @param is_last When TRUE, next payload field is set to 0, otherwise to 3
|
||||
*/
|
||||
void (*set_is_last_transform) (transform_substructure_t *this, bool is_last);
|
||||
|
||||
/**
|
||||
* @brief Checks if this is the last transform.
|
||||
*
|
||||
* @param this calling transform_substructure_t object
|
||||
* @return TRUE if this is the last Transform, FALSE otherwise
|
||||
*/
|
||||
bool (*get_is_last_transform) (transform_substructure_t *this);
|
||||
|
||||
/**
|
||||
* @brief Sets transform type of the current transform substructure.
|
||||
*
|
||||
* @param this calling transform_substructure_t object
|
||||
* @param type type value to set
|
||||
*/
|
||||
void (*set_transform_type) (transform_substructure_t *this,u_int8_t type);
|
||||
|
||||
/**
|
||||
* @brief get transform type of the current transform.
|
||||
*
|
||||
* @param this calling transform_substructure_t object
|
||||
* @return Transform type of current transform substructure.
|
||||
*/
|
||||
u_int8_t (*get_transform_type) (transform_substructure_t *this);
|
||||
|
||||
/**
|
||||
* @brief Sets transform id of the current transform substructure.
|
||||
*
|
||||
* @param this calling transform_substructure_t object
|
||||
* @param id transform id to set
|
||||
*/
|
||||
void (*set_transform_id) (transform_substructure_t *this,u_int16_t id);
|
||||
|
||||
/**
|
||||
* @brief get transform id of the current transform.
|
||||
*
|
||||
* @param this calling transform_substructure_t object
|
||||
* @return Transform id of current transform substructure.
|
||||
*/
|
||||
u_int16_t (*get_transform_id) (transform_substructure_t *this);
|
||||
|
||||
/**
|
||||
* @brief get transform id of the current transform.
|
||||
*
|
||||
* @param this calling transform_substructure_t object
|
||||
* @param key_length The key length is written to this location
|
||||
* @return
|
||||
* - SUCCESS if a key length attribute is contained
|
||||
* - FAILED if no key length attribute is part of this
|
||||
* transform or key length uses more then 16 bit!
|
||||
*/
|
||||
status_t (*get_key_length) (transform_substructure_t *this,u_int16_t *key_length);
|
||||
|
||||
/**
|
||||
* @brief Clones an transform_substructure_t object.
|
||||
*
|
||||
* @param this transform_substructure_t object to clone
|
||||
* @return cloned transform_substructure_t object
|
||||
*/
|
||||
transform_substructure_t* (*clone) (transform_substructure_t *this);
|
||||
|
||||
/**
|
||||
* @brief Destroys an transform_substructure_t object.
|
||||
*
|
||||
* @param this transform_substructure_t object to destroy
|
||||
*/
|
||||
void (*destroy) (transform_substructure_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Creates an empty transform_substructure_t object.
|
||||
*
|
||||
* @return created transform_substructure_t object
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
transform_substructure_t *transform_substructure_create();
|
||||
|
||||
/**
|
||||
* @brief Creates an empty transform_substructure_t object.
|
||||
*
|
||||
* The key length is used for the transport types ENCRYPTION_ALGORITHM,
|
||||
* PSEUDO_RANDOM_FUNCTION, INTEGRITY_ALGORITHM. For all
|
||||
* other transport types the key_length parameter is not used
|
||||
*
|
||||
* @param transform_type type of transform to create
|
||||
* @param transform_id transform id specifying the specific algorithm of a transform type
|
||||
* @param key_length Key length for key lenght attribute
|
||||
* @return transform_substructure_t object
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
transform_substructure_t *transform_substructure_create_type(transform_type_t transform_type, u_int16_t transform_id, u_int16_t key_length);
|
||||
|
||||
#endif /*TRANSFORM_SUBSTRUCTURE_H_*/
|
||||
@@ -0,0 +1,365 @@
|
||||
/**
|
||||
* @file ts_payload.c
|
||||
*
|
||||
* @brief Implementation of ts_payload_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "ts_payload.h"
|
||||
|
||||
#include <encoding/payloads/encodings.h>
|
||||
#include <utils/linked_list.h>
|
||||
|
||||
typedef struct private_ts_payload_t private_ts_payload_t;
|
||||
|
||||
/**
|
||||
* Private data of an ts_payload_t object.
|
||||
*
|
||||
*/
|
||||
struct private_ts_payload_t {
|
||||
/**
|
||||
* Public ts_payload_t interface.
|
||||
*/
|
||||
ts_payload_t public;
|
||||
|
||||
/**
|
||||
* TRUE if this TS payload is of type TSi, FALSE for TSr.
|
||||
*/
|
||||
bool is_initiator;
|
||||
|
||||
/**
|
||||
* Next payload type.
|
||||
*/
|
||||
u_int8_t next_payload;
|
||||
|
||||
/**
|
||||
* Critical flag.
|
||||
*/
|
||||
bool critical;
|
||||
|
||||
/**
|
||||
* Length of this payload.
|
||||
*/
|
||||
u_int16_t payload_length;
|
||||
|
||||
/**
|
||||
* Number of traffic selectors
|
||||
*/
|
||||
u_int8_t number_of_traffic_selectors;
|
||||
|
||||
/**
|
||||
* Contains the traffic selectors of type traffic_selector_substructure_t.
|
||||
*/
|
||||
linked_list_t *traffic_selectors;
|
||||
|
||||
/**
|
||||
* @brief Computes the length of this payload.
|
||||
*
|
||||
* @param this calling private_ts_payload_t object
|
||||
*/
|
||||
void (*compute_length) (private_ts_payload_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Encoding rules to parse or generate a TS payload
|
||||
*
|
||||
* The defined offsets are the positions in a object of type
|
||||
* private_ts_payload_t.
|
||||
*
|
||||
*/
|
||||
encoding_rule_t ts_payload_encodings[] = {
|
||||
/* 1 Byte next payload type, stored in the field next_payload */
|
||||
{ U_INT_8, offsetof(private_ts_payload_t, next_payload) },
|
||||
/* the critical bit */
|
||||
{ FLAG, offsetof(private_ts_payload_t, critical) },
|
||||
/* 7 Bit reserved bits, nowhere stored */
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
/* Length of the whole payload*/
|
||||
{ PAYLOAD_LENGTH, offsetof(private_ts_payload_t, payload_length)},
|
||||
/* 1 Byte TS type*/
|
||||
{ U_INT_8, offsetof(private_ts_payload_t, number_of_traffic_selectors) },
|
||||
/* 3 reserved bytes */
|
||||
{ RESERVED_BYTE, 0 },
|
||||
{ RESERVED_BYTE, 0 },
|
||||
{ RESERVED_BYTE, 0 },
|
||||
/* some ts data bytes, length is defined in PAYLOAD_LENGTH */
|
||||
{ TRAFFIC_SELECTORS, offsetof(private_ts_payload_t, traffic_selectors) }
|
||||
};
|
||||
|
||||
/*
|
||||
1 2 3
|
||||
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 !C! RESERVED ! Payload Length !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! Number of TSs ! RESERVED !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! !
|
||||
~ <Traffic Selectors> ~
|
||||
! !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.verify.
|
||||
*/
|
||||
static status_t verify(private_ts_payload_t *this)
|
||||
{
|
||||
iterator_t *iterator;
|
||||
status_t status = SUCCESS;
|
||||
|
||||
if (this->number_of_traffic_selectors != (this->traffic_selectors->get_count(this->traffic_selectors)))
|
||||
{
|
||||
/* must be the same */
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
iterator = this->traffic_selectors->create_iterator(this->traffic_selectors,TRUE);
|
||||
while(iterator->has_next(iterator))
|
||||
{
|
||||
payload_t *current_traffic_selector;
|
||||
iterator->current(iterator,(void **)¤t_traffic_selector);
|
||||
|
||||
status = current_traffic_selector->verify(current_traffic_selector);
|
||||
if (status != SUCCESS)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ts_payload_t.get_encoding_rules.
|
||||
*/
|
||||
static void get_encoding_rules(private_ts_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
|
||||
{
|
||||
*rules = ts_payload_encodings;
|
||||
*rule_count = sizeof(ts_payload_encodings) / sizeof(encoding_rule_t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_type.
|
||||
*/
|
||||
static payload_type_t get_payload_type(private_ts_payload_t *this)
|
||||
{
|
||||
if (this->is_initiator)
|
||||
{
|
||||
return TRAFFIC_SELECTOR_INITIATOR;
|
||||
}
|
||||
else
|
||||
{
|
||||
return TRAFFIC_SELECTOR_RESPONDER;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_next_type.
|
||||
*/
|
||||
static payload_type_t get_next_type(private_ts_payload_t *this)
|
||||
{
|
||||
return (this->next_payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.set_next_type.
|
||||
*/
|
||||
static void set_next_type(private_ts_payload_t *this,payload_type_t type)
|
||||
{
|
||||
this->next_payload = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_length.
|
||||
*/
|
||||
static size_t get_length(private_ts_payload_t *this)
|
||||
{
|
||||
this->compute_length(this);
|
||||
return this->payload_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ts_payload_t.get_initiator.
|
||||
*/
|
||||
static bool get_initiator (private_ts_payload_t *this)
|
||||
{
|
||||
return (this->is_initiator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ts_payload_t.set_initiator.
|
||||
*/
|
||||
static void set_initiator (private_ts_payload_t *this,bool is_initiator)
|
||||
{
|
||||
this->is_initiator = is_initiator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ts_payload_t.add_traffic_selector_substructure.
|
||||
*/
|
||||
static void add_traffic_selector_substructure (private_ts_payload_t *this,traffic_selector_substructure_t *traffic_selector)
|
||||
{
|
||||
this->traffic_selectors->insert_last(this->traffic_selectors,traffic_selector);
|
||||
this->number_of_traffic_selectors = this->traffic_selectors->get_count(this->traffic_selectors);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ts_payload_t.create_traffic_selector_substructure_iterator.
|
||||
*/
|
||||
static iterator_t * create_traffic_selector_substructure_iterator (private_ts_payload_t *this, bool forward)
|
||||
{
|
||||
return this->traffic_selectors->create_iterator(this->traffic_selectors,forward);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ts_payload_t.get_traffic_selectors.
|
||||
*/
|
||||
static linked_list_t *get_traffic_selectors(private_ts_payload_t *this)
|
||||
{
|
||||
traffic_selector_t *ts;
|
||||
iterator_t *iterator;
|
||||
linked_list_t *ts_list = linked_list_create();
|
||||
|
||||
iterator = this->traffic_selectors->create_iterator(this->traffic_selectors, TRUE);
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
traffic_selector_substructure_t *ts_substructure;
|
||||
iterator->current(iterator, (void**)&ts_substructure);
|
||||
ts = ts_substructure->get_traffic_selector(ts_substructure);
|
||||
ts_list->insert_last(ts_list, (void*)ts);
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
return ts_list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of private_ts_payload_t.compute_length.
|
||||
*/
|
||||
static void compute_length (private_ts_payload_t *this)
|
||||
{
|
||||
iterator_t *iterator;
|
||||
size_t ts_count = 0;
|
||||
size_t length = TS_PAYLOAD_HEADER_LENGTH;
|
||||
iterator = this->traffic_selectors->create_iterator(this->traffic_selectors,TRUE);
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
payload_t * current_traffic_selector;
|
||||
iterator->current(iterator,(void **) ¤t_traffic_selector);
|
||||
length += current_traffic_selector->get_length(current_traffic_selector);
|
||||
ts_count++;
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
this->number_of_traffic_selectors= ts_count;
|
||||
this->payload_length = length;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.destroy and ts_payload_t.destroy.
|
||||
*/
|
||||
static void destroy(private_ts_payload_t *this)
|
||||
{
|
||||
while (this->traffic_selectors->get_count(this->traffic_selectors) > 0)
|
||||
{
|
||||
payload_t *current_traffic_selector;
|
||||
|
||||
this->traffic_selectors->remove_last(this->traffic_selectors,(void **) ¤t_traffic_selector);
|
||||
|
||||
current_traffic_selector->destroy(current_traffic_selector);
|
||||
}
|
||||
|
||||
this->traffic_selectors->destroy(this->traffic_selectors);
|
||||
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
ts_payload_t *ts_payload_create(bool is_initiator)
|
||||
{
|
||||
private_ts_payload_t *this = malloc_thing(private_ts_payload_t);
|
||||
|
||||
/* interface functions */
|
||||
this->public.payload_interface.verify = (status_t (*) (payload_t *))verify;
|
||||
this->public.payload_interface.get_encoding_rules = (void (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules;
|
||||
this->public.payload_interface.get_length = (size_t (*) (payload_t *)) get_length;
|
||||
this->public.payload_interface.get_next_type = (payload_type_t (*) (payload_t *)) get_next_type;
|
||||
this->public.payload_interface.set_next_type = (void (*) (payload_t *,payload_type_t)) set_next_type;
|
||||
this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_payload_type;
|
||||
this->public.payload_interface.destroy = (void (*) (payload_t *))destroy;
|
||||
|
||||
/* public functions */
|
||||
this->public.destroy = (void (*) (ts_payload_t *)) destroy;
|
||||
this->public.get_initiator = (bool (*) (ts_payload_t *)) get_initiator;
|
||||
this->public.set_initiator = (void (*) (ts_payload_t *,bool)) set_initiator;
|
||||
this->public.add_traffic_selector_substructure = (void (*) (ts_payload_t *,traffic_selector_substructure_t *)) add_traffic_selector_substructure;
|
||||
this->public.create_traffic_selector_substructure_iterator = (iterator_t* (*) (ts_payload_t *,bool)) create_traffic_selector_substructure_iterator;
|
||||
this->public.get_traffic_selectors = (linked_list_t *(*) (ts_payload_t *)) get_traffic_selectors;
|
||||
|
||||
/* private functions */
|
||||
this->compute_length = compute_length;
|
||||
|
||||
/* private variables */
|
||||
this->critical = FALSE;
|
||||
this->next_payload = NO_PAYLOAD;
|
||||
this->payload_length =TS_PAYLOAD_HEADER_LENGTH;
|
||||
this->is_initiator = is_initiator;
|
||||
this->number_of_traffic_selectors = 0;
|
||||
this->traffic_selectors = linked_list_create();
|
||||
|
||||
return &(this->public);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
ts_payload_t *ts_payload_create_from_traffic_selectors(bool is_initiator, linked_list_t *traffic_selectors)
|
||||
{
|
||||
iterator_t *iterator;
|
||||
traffic_selector_t *ts;
|
||||
traffic_selector_substructure_t *ts_substructure;
|
||||
private_ts_payload_t *this;
|
||||
|
||||
this = (private_ts_payload_t*)ts_payload_create(is_initiator);
|
||||
|
||||
iterator = traffic_selectors->create_iterator(traffic_selectors, TRUE);
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
iterator->current(iterator, (void**)&ts);
|
||||
ts_substructure = traffic_selector_substructure_create_from_traffic_selector(ts);
|
||||
this->public.add_traffic_selector_substructure(&(this->public), ts_substructure);
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
return &(this->public);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
/**
|
||||
* @file ts_payload.h
|
||||
*
|
||||
* @brief Interface of ts_payload_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TS_PAYLOAD_H_
|
||||
#define TS_PAYLOAD_H_
|
||||
|
||||
#include <types.h>
|
||||
#include <utils/linked_list.h>
|
||||
#include <config/traffic_selector.h>
|
||||
#include <encoding/payloads/payload.h>
|
||||
#include <encoding/payloads/traffic_selector_substructure.h>
|
||||
|
||||
/**
|
||||
* Length of a TS payload without the Traffic selectors.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
#define TS_PAYLOAD_HEADER_LENGTH 8
|
||||
|
||||
|
||||
typedef struct ts_payload_t ts_payload_t;
|
||||
|
||||
/**
|
||||
* @brief Class representing an IKEv2 TS payload.
|
||||
*
|
||||
* The TS payload format is described in RFC section 3.13.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - ts_payload_create()
|
||||
* - ts_payload_create_from_traffic_selectors()
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
struct ts_payload_t {
|
||||
/**
|
||||
* The payload_t interface.
|
||||
*/
|
||||
payload_t payload_interface;
|
||||
|
||||
/**
|
||||
* @brief Get the type of TSpayload (TSi or TSr).
|
||||
*
|
||||
* @param this calling id_payload_t object
|
||||
* @return
|
||||
* - TRUE if this payload is of type TSi
|
||||
* - FALSE if this payload is of type TSr
|
||||
*/
|
||||
bool (*get_initiator) (ts_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Set the type of TS payload (TSi or TSr).
|
||||
*
|
||||
* @param this calling id_payload_t object
|
||||
* @param is_initiator
|
||||
* - TRUE if this payload is of type TSi
|
||||
* - FALSE if this payload is of type TSr
|
||||
*/
|
||||
void (*set_initiator) (ts_payload_t *this,bool is_initiator);
|
||||
|
||||
/**
|
||||
* @brief Adds a traffic_selector_substructure_t object to this object.
|
||||
*
|
||||
* @warning The added traffic_selector_substructure_t object is
|
||||
* getting destroyed in destroy function of ts_payload_t.
|
||||
*
|
||||
* @param this calling ts_payload_t object
|
||||
* @param traffic_selector traffic_selector_substructure_t object to add
|
||||
*/
|
||||
void (*add_traffic_selector_substructure) (ts_payload_t *this,traffic_selector_substructure_t *traffic_selector);
|
||||
|
||||
/**
|
||||
* @brief Creates an iterator of stored traffic_selector_substructure_t objects.
|
||||
*
|
||||
* @warning The created iterator has to get destroyed by the caller!
|
||||
*
|
||||
* @warning When removing an traffic_selector_substructure_t object
|
||||
* using this iterator, the length of this payload
|
||||
* has to get refreshed by calling payload_t.get_length!
|
||||
*
|
||||
* @param this calling ts_payload_t object
|
||||
* @param[in] forward iterator direction (TRUE: front to end)
|
||||
* @return created iterator_t object
|
||||
*/
|
||||
iterator_t *(*create_traffic_selector_substructure_iterator) (ts_payload_t *this, bool forward);
|
||||
|
||||
/**
|
||||
* @brief Get a list of nested traffic selectors as traffic_selector_t.
|
||||
*
|
||||
* Resulting list and its traffic selectors must be destroyed after usage
|
||||
*
|
||||
* @param this calling ts_payload_t object
|
||||
* @return list of traffic selectors
|
||||
*/
|
||||
linked_list_t *(*get_traffic_selectors) (ts_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Destroys an ts_payload_t object.
|
||||
*
|
||||
* @param this ts_payload_t object to destroy
|
||||
*/
|
||||
void (*destroy) (ts_payload_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Creates an empty ts_payload_t object.
|
||||
*
|
||||
*
|
||||
* @param is_initiator
|
||||
* - TRUE if this payload is of type TSi
|
||||
* - FALSE if this payload is of type TSr
|
||||
* @return ts_payload_t object
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
ts_payload_t *ts_payload_create(bool is_initiator);
|
||||
|
||||
/**
|
||||
* @brief Creates ts_payload with a list of traffic_selector_t
|
||||
*
|
||||
*
|
||||
* @param is_initiator
|
||||
* - TRUE if this payload is of type TSi
|
||||
* - FALSE if this payload is of type TSr
|
||||
* @param traffic_selectors list of traffic selectors to include
|
||||
* @return ts_payload_t object
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
ts_payload_t *ts_payload_create_from_traffic_selectors(bool is_initiator, linked_list_t *traffic_selectors);
|
||||
|
||||
|
||||
#endif /* TS_PAYLOAD_H_ */
|
||||
@@ -0,0 +1,207 @@
|
||||
/**
|
||||
* @file unknown_payload.c
|
||||
*
|
||||
* @brief Implementation of unknown_payload_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "unknown_payload.h"
|
||||
|
||||
|
||||
|
||||
typedef struct private_unknown_payload_t private_unknown_payload_t;
|
||||
|
||||
/**
|
||||
* Private data of an unknown_payload_t object.
|
||||
*/
|
||||
struct private_unknown_payload_t {
|
||||
|
||||
/**
|
||||
* Public unknown_payload_t interface.
|
||||
*/
|
||||
unknown_payload_t public;
|
||||
|
||||
/**
|
||||
* Next payload type.
|
||||
*/
|
||||
u_int8_t next_payload;
|
||||
|
||||
/**
|
||||
* Critical flag.
|
||||
*/
|
||||
bool critical;
|
||||
|
||||
/**
|
||||
* Length of this payload.
|
||||
*/
|
||||
u_int16_t payload_length;
|
||||
|
||||
/**
|
||||
* The contained data.
|
||||
*/
|
||||
chunk_t data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Encoding rules to parse an payload which is not further specified.
|
||||
*
|
||||
* The defined offsets are the positions in a object of type
|
||||
* private_unknown_payload_t.
|
||||
*
|
||||
*/
|
||||
encoding_rule_t unknown_payload_encodings[] = {
|
||||
/* 1 Byte next payload type, stored in the field next_payload */
|
||||
{ U_INT_8, offsetof(private_unknown_payload_t, next_payload)},
|
||||
/* the critical bit */
|
||||
{ FLAG, offsetof(private_unknown_payload_t, critical) },
|
||||
/* 7 Bit reserved bits, nowhere stored */
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
/* Length of the whole payload*/
|
||||
{ PAYLOAD_LENGTH, offsetof(private_unknown_payload_t, payload_length)},
|
||||
/* some unknown data bytes, length is defined in PAYLOAD_LENGTH */
|
||||
{ UNKNOWN_DATA, offsetof(private_unknown_payload_t, data) }
|
||||
};
|
||||
|
||||
/*
|
||||
1 2 3
|
||||
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 !C! RESERVED ! Payload Length !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! !
|
||||
~ Data of any type ~
|
||||
! !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.verify.
|
||||
*/
|
||||
static status_t verify(private_unknown_payload_t *this)
|
||||
{
|
||||
/* can't do any checks, so we assume its good */
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_encoding_rules.
|
||||
*/
|
||||
static void get_encoding_rules(private_unknown_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
|
||||
{
|
||||
*rules = unknown_payload_encodings;
|
||||
*rule_count = sizeof(unknown_payload_encodings) / sizeof(encoding_rule_t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_type.
|
||||
*/
|
||||
static payload_type_t get_payload_type(private_unknown_payload_t *this)
|
||||
{
|
||||
return UNKNOWN_PAYLOAD;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_next_type.
|
||||
*/
|
||||
static payload_type_t get_next_type(private_unknown_payload_t *this)
|
||||
{
|
||||
return (this->next_payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.set_next_type.
|
||||
*/
|
||||
static void set_next_type(private_unknown_payload_t *this,payload_type_t type)
|
||||
{
|
||||
this->next_payload = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_length.
|
||||
*/
|
||||
static size_t get_length(private_unknown_payload_t *this)
|
||||
{
|
||||
return this->payload_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of unknown_payload_t.get_data.
|
||||
*/
|
||||
static bool is_critical(private_unknown_payload_t *this)
|
||||
{
|
||||
return this->critical;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of unknown_payload_t.get_data.
|
||||
*/
|
||||
static chunk_t get_data (private_unknown_payload_t *this)
|
||||
{
|
||||
return (this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.destroy and unknown_payload_t.destroy.
|
||||
*/
|
||||
static void destroy(private_unknown_payload_t *this)
|
||||
{
|
||||
if (this->data.ptr != NULL)
|
||||
{
|
||||
chunk_free(&(this->data));
|
||||
}
|
||||
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
unknown_payload_t *unknown_payload_create()
|
||||
{
|
||||
private_unknown_payload_t *this = malloc_thing(private_unknown_payload_t);
|
||||
|
||||
/* interface functions */
|
||||
this->public.payload_interface.verify = (status_t (*) (payload_t *))verify;
|
||||
this->public.payload_interface.get_encoding_rules = (void (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules;
|
||||
this->public.payload_interface.get_length = (size_t (*) (payload_t *)) get_length;
|
||||
this->public.payload_interface.get_next_type = (payload_type_t (*) (payload_t *)) get_next_type;
|
||||
this->public.payload_interface.set_next_type = (void (*) (payload_t *,payload_type_t)) set_next_type;
|
||||
this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_payload_type;
|
||||
this->public.payload_interface.destroy = (void (*) (payload_t *))destroy;
|
||||
|
||||
/* public functions */
|
||||
this->public.destroy = (void (*) (unknown_payload_t *)) destroy;
|
||||
this->public.is_critical = (bool (*) (unknown_payload_t *)) is_critical;
|
||||
this->public.get_data = (chunk_t (*) (unknown_payload_t *)) get_data;
|
||||
|
||||
/* private variables */
|
||||
this->critical = FALSE;
|
||||
this->next_payload = NO_PAYLOAD;
|
||||
this->payload_length = UNKNOWN_PAYLOAD_HEADER_LENGTH;
|
||||
this->data = CHUNK_INITIALIZER;
|
||||
|
||||
return (&(this->public));
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* @file unknown_payload.h
|
||||
*
|
||||
* @brief Interface of unknown_payload_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef UNKNOWN_PAYLOAD_H_
|
||||
#define UNKNOWN_PAYLOAD_H_
|
||||
|
||||
#include <types.h>
|
||||
#include <encoding/payloads/payload.h>
|
||||
|
||||
/**
|
||||
* Header length of the unknown payload.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
#define UNKNOWN_PAYLOAD_HEADER_LENGTH 4
|
||||
|
||||
|
||||
typedef struct unknown_payload_t unknown_payload_t;
|
||||
|
||||
/**
|
||||
* @brief Payload which can't be processed further.
|
||||
*
|
||||
* When the parser finds an unknown payload, he builds an instance of
|
||||
* this class. This allows further processing of this payload, such as
|
||||
* a check for the critical bit in the header.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - unknown_payload_create()
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
struct unknown_payload_t {
|
||||
|
||||
/**
|
||||
* The payload_t interface.
|
||||
*/
|
||||
payload_t payload_interface;
|
||||
|
||||
/**
|
||||
* @brief Get the raw data of this payload, without
|
||||
* the generic payload header.
|
||||
*
|
||||
* Returned data are NOT copied and must not be freed.
|
||||
*
|
||||
* @param this calling unknown_payload_t object
|
||||
* @return data as chunk_t
|
||||
*/
|
||||
chunk_t (*get_data) (unknown_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get the critical flag.
|
||||
*
|
||||
* @param this calling unknown_payload_t object
|
||||
* @return TRUE if payload is critical, FALSE if not
|
||||
*/
|
||||
bool (*is_critical) (unknown_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Destroys an unknown_payload_t object.
|
||||
*
|
||||
* @param this unknown_payload_t object to destroy
|
||||
*/
|
||||
void (*destroy) (unknown_payload_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Creates an empty unknown_payload_t object.
|
||||
*
|
||||
* @return unknown_payload_t object
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
unknown_payload_t *unknown_payload_create();
|
||||
|
||||
|
||||
#endif /* UNKNOWN_PAYLOAD_H_ */
|
||||
@@ -0,0 +1,227 @@
|
||||
/**
|
||||
* @file vendor_id_payload.c
|
||||
*
|
||||
* @brief Implementation of vendor_id_payload_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "vendor_id_payload.h"
|
||||
|
||||
|
||||
typedef struct private_vendor_id_payload_t private_vendor_id_payload_t;
|
||||
|
||||
/**
|
||||
* Private data of an vendor_id_payload_t object.
|
||||
*
|
||||
*/
|
||||
struct private_vendor_id_payload_t {
|
||||
/**
|
||||
* Public vendor_id_payload_t interface.
|
||||
*/
|
||||
vendor_id_payload_t public;
|
||||
|
||||
/**
|
||||
* Next payload type.
|
||||
*/
|
||||
u_int8_t next_payload;
|
||||
|
||||
/**
|
||||
* Critical flag.
|
||||
*/
|
||||
bool critical;
|
||||
|
||||
/**
|
||||
* Length of this payload.
|
||||
*/
|
||||
u_int16_t payload_length;
|
||||
|
||||
/**
|
||||
* The contained vendor_id data value.
|
||||
*/
|
||||
chunk_t vendor_id_data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Encoding rules to parse or generate a VENDOR ID payload
|
||||
*
|
||||
* The defined offsets are the positions in a object of type
|
||||
* private_vendor_id_payload_t.
|
||||
*
|
||||
*/
|
||||
encoding_rule_t vendor_id_payload_encodings[] = {
|
||||
/* 1 Byte next payload type, stored in the field next_payload */
|
||||
{ U_INT_8, offsetof(private_vendor_id_payload_t, next_payload) },
|
||||
/* the critical bit */
|
||||
{ FLAG, offsetof(private_vendor_id_payload_t, critical) },
|
||||
/* 7 Bit reserved bits, nowhere stored */
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
{ RESERVED_BIT, 0 },
|
||||
/* Length of the whole payload*/
|
||||
{ PAYLOAD_LENGTH, offsetof(private_vendor_id_payload_t, payload_length)},
|
||||
/* some vendor_id data bytes, length is defined in PAYLOAD_LENGTH */
|
||||
{ VID_DATA, offsetof(private_vendor_id_payload_t, vendor_id_data) }
|
||||
};
|
||||
|
||||
/*
|
||||
1 2 3
|
||||
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 !C! RESERVED ! Payload Length !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! Cert Encoding ! !
|
||||
+-+-+-+-+-+-+-+-+ !
|
||||
~ Certificate Data ~
|
||||
! !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.verify.
|
||||
*/
|
||||
static status_t verify(private_vendor_id_payload_t *this)
|
||||
{
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of vendor_id_payload_t.get_encoding_rules.
|
||||
*/
|
||||
static void get_encoding_rules(private_vendor_id_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
|
||||
{
|
||||
*rules = vendor_id_payload_encodings;
|
||||
*rule_count = sizeof(vendor_id_payload_encodings) / sizeof(encoding_rule_t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_type.
|
||||
*/
|
||||
static payload_type_t get_payload_type(private_vendor_id_payload_t *this)
|
||||
{
|
||||
return VENDOR_ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_next_type.
|
||||
*/
|
||||
static payload_type_t get_next_type(private_vendor_id_payload_t *this)
|
||||
{
|
||||
return (this->next_payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.set_next_type.
|
||||
*/
|
||||
static void set_next_type(private_vendor_id_payload_t *this,payload_type_t type)
|
||||
{
|
||||
this->next_payload = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.get_length.
|
||||
*/
|
||||
static size_t get_length(private_vendor_id_payload_t *this)
|
||||
{
|
||||
return this->payload_length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of vendor_id_payload_t.set_data.
|
||||
*/
|
||||
static void set_data (private_vendor_id_payload_t *this, chunk_t data)
|
||||
{
|
||||
if (this->vendor_id_data.ptr != NULL)
|
||||
{
|
||||
chunk_free(&(this->vendor_id_data));
|
||||
}
|
||||
this->vendor_id_data.ptr = clalloc(data.ptr,data.len);
|
||||
this->vendor_id_data.len = data.len;
|
||||
this->payload_length = VENDOR_ID_PAYLOAD_HEADER_LENGTH + this->vendor_id_data.len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of vendor_id_payload_t.get_data.
|
||||
*/
|
||||
static chunk_t get_data (private_vendor_id_payload_t *this)
|
||||
{
|
||||
return (this->vendor_id_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of vendor_id_payload_t.get_data_clone.
|
||||
*/
|
||||
static chunk_t get_data_clone (private_vendor_id_payload_t *this)
|
||||
{
|
||||
chunk_t cloned_data;
|
||||
if (this->vendor_id_data.ptr == NULL)
|
||||
{
|
||||
return (this->vendor_id_data);
|
||||
}
|
||||
cloned_data.ptr = clalloc(this->vendor_id_data.ptr,this->vendor_id_data.len);
|
||||
cloned_data.len = this->vendor_id_data.len;
|
||||
return cloned_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of payload_t.destroy and vendor_id_payload_t.destroy.
|
||||
*/
|
||||
static void destroy(private_vendor_id_payload_t *this)
|
||||
{
|
||||
if (this->vendor_id_data.ptr != NULL)
|
||||
{
|
||||
chunk_free(&(this->vendor_id_data));
|
||||
}
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
vendor_id_payload_t *vendor_id_payload_create()
|
||||
{
|
||||
private_vendor_id_payload_t *this = malloc_thing(private_vendor_id_payload_t);
|
||||
|
||||
/* interface functions */
|
||||
this->public.payload_interface.verify = (status_t (*) (payload_t *))verify;
|
||||
this->public.payload_interface.get_encoding_rules = (void (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules;
|
||||
this->public.payload_interface.get_length = (size_t (*) (payload_t *)) get_length;
|
||||
this->public.payload_interface.get_next_type = (payload_type_t (*) (payload_t *)) get_next_type;
|
||||
this->public.payload_interface.set_next_type = (void (*) (payload_t *,payload_type_t)) set_next_type;
|
||||
this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_payload_type;
|
||||
this->public.payload_interface.destroy = (void (*) (payload_t *))destroy;
|
||||
|
||||
/* public functions */
|
||||
this->public.destroy = (void (*) (vendor_id_payload_t *)) destroy;
|
||||
this->public.set_data = (void (*) (vendor_id_payload_t *,chunk_t)) set_data;
|
||||
this->public.get_data_clone = (chunk_t (*) (vendor_id_payload_t *)) get_data_clone;
|
||||
this->public.get_data = (chunk_t (*) (vendor_id_payload_t *)) get_data;
|
||||
|
||||
/* private variables */
|
||||
this->critical = FALSE;
|
||||
this->next_payload = NO_PAYLOAD;
|
||||
this->payload_length = VENDOR_ID_PAYLOAD_HEADER_LENGTH;
|
||||
this->vendor_id_data = CHUNK_INITIALIZER;
|
||||
|
||||
return (&(this->public));
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/**
|
||||
* @file vendor_id_payload.h
|
||||
*
|
||||
* @brief Interface of vendor_id_payload_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef VENDOR_ID_PAYLOAD_H_
|
||||
#define VENDOR_ID_PAYLOAD_H_
|
||||
|
||||
#include <types.h>
|
||||
#include <encoding/payloads/payload.h>
|
||||
|
||||
/**
|
||||
* Length of a VENDOR ID payload without the VID data in bytes.
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
#define VENDOR_ID_PAYLOAD_HEADER_LENGTH 4
|
||||
|
||||
|
||||
typedef struct vendor_id_payload_t vendor_id_payload_t;
|
||||
|
||||
/**
|
||||
* @brief Class representing an IKEv2 VENDOR ID payload.
|
||||
*
|
||||
* The VENDOR ID payload format is described in RFC section 3.12.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - vendor_id_payload_create()
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
struct vendor_id_payload_t {
|
||||
/**
|
||||
* The payload_t interface.
|
||||
*/
|
||||
payload_t payload_interface;
|
||||
|
||||
/**
|
||||
* @brief Set the VID data.
|
||||
*
|
||||
* Data are getting cloned.
|
||||
*
|
||||
* @param this calling vendor_id_payload_t object
|
||||
* @param data VID data as chunk_t
|
||||
*/
|
||||
void (*set_data) (vendor_id_payload_t *this, chunk_t data);
|
||||
|
||||
/**
|
||||
* @brief Get the VID data.
|
||||
*
|
||||
* Returned data are a copy of the internal one.
|
||||
*
|
||||
* @param this calling vendor_id_payload_t object
|
||||
* @return VID data as chunk_t
|
||||
*/
|
||||
chunk_t (*get_data_clone) (vendor_id_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get the VID data.
|
||||
*
|
||||
* Returned data are NOT copied.
|
||||
*
|
||||
* @param this calling vendor_id_payload_t object
|
||||
* @return VID data as chunk_t
|
||||
*/
|
||||
chunk_t (*get_data) (vendor_id_payload_t *this);
|
||||
|
||||
/**
|
||||
* @brief Destroys an vendor_id_payload_t object.
|
||||
*
|
||||
* @param this vendor_id_payload_t object to destroy
|
||||
*/
|
||||
void (*destroy) (vendor_id_payload_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Creates an empty vendor_id_payload_t object.
|
||||
*
|
||||
* @return vendor_id_payload_t object
|
||||
*
|
||||
* @ingroup payloads
|
||||
*/
|
||||
vendor_id_payload_t *vendor_id_payload_create();
|
||||
|
||||
|
||||
#endif /* VENDOR_ID_PAYLOAD_H_ */
|
||||
@@ -0,0 +1,24 @@
|
||||
# Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
# Hochschule fuer Technik Rapperswil
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the
|
||||
# Free Software Foundation; either version 2 of the License, or (at your
|
||||
# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# for more details.
|
||||
#
|
||||
|
||||
NETWORK_DIR= $(CHARON_DIR)network/
|
||||
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)packet.o
|
||||
$(BUILD_DIR)packet.o : $(NETWORK_DIR)packet.c $(NETWORK_DIR)packet.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)socket.o
|
||||
$(BUILD_DIR)socket.o : $(NETWORK_DIR)socket.c $(NETWORK_DIR)socket.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
@@ -0,0 +1,189 @@
|
||||
/**
|
||||
* @file packet.c
|
||||
*
|
||||
* @brief Implementation of packet_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
|
||||
#include "packet.h"
|
||||
|
||||
|
||||
typedef struct private_packet_t private_packet_t;
|
||||
|
||||
/**
|
||||
* Private data of an packet_t object.
|
||||
*/
|
||||
struct private_packet_t {
|
||||
|
||||
/**
|
||||
* Public part of a packet_t object.
|
||||
*/
|
||||
packet_t public;
|
||||
|
||||
/**
|
||||
* source address
|
||||
*/
|
||||
host_t *source;
|
||||
|
||||
/**
|
||||
* destination address
|
||||
*/
|
||||
host_t *destination;
|
||||
|
||||
/**
|
||||
* message data
|
||||
*/
|
||||
chunk_t data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Implements packet_t.get_source
|
||||
*/
|
||||
static void set_source(private_packet_t *this, host_t *source)
|
||||
{
|
||||
if (this->source)
|
||||
{
|
||||
this->source->destroy(this->source);
|
||||
}
|
||||
this->source = source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements packet_t.set_destination
|
||||
*/
|
||||
static void set_destination(private_packet_t *this, host_t *destination)
|
||||
{
|
||||
if (this->destination)
|
||||
{
|
||||
this->destination->destroy(this->destination);
|
||||
}
|
||||
this->destination = destination;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements packet_t.get_source
|
||||
*/
|
||||
static host_t *get_source(private_packet_t *this)
|
||||
{
|
||||
return this->source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements packet_t.get_destination
|
||||
*/
|
||||
static host_t *get_destination(private_packet_t *this)
|
||||
{
|
||||
return this->destination;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements packet_t.get_data
|
||||
*/
|
||||
static chunk_t get_data(private_packet_t *this)
|
||||
{
|
||||
return this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements packet_t.set_data
|
||||
*/
|
||||
static void set_data(private_packet_t *this, chunk_t data)
|
||||
{
|
||||
free(this->data.ptr);
|
||||
this->data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements packet_t.destroy.
|
||||
*/
|
||||
static void destroy(private_packet_t *this)
|
||||
{
|
||||
if (this->source != NULL)
|
||||
{
|
||||
this->source->destroy(this->source);
|
||||
}
|
||||
if (this->destination != NULL)
|
||||
{
|
||||
this->destination->destroy(this->destination);
|
||||
}
|
||||
free(this->data.ptr);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements packet_t.clone.
|
||||
*/
|
||||
static packet_t *clone(private_packet_t *this)
|
||||
{
|
||||
private_packet_t *other = (private_packet_t*)packet_create();
|
||||
|
||||
if (this->destination != NULL)
|
||||
{
|
||||
other->destination = this->destination->clone(this->destination);
|
||||
}
|
||||
else
|
||||
{
|
||||
other->destination = NULL;
|
||||
}
|
||||
|
||||
if (this->source != NULL)
|
||||
{
|
||||
other->source = this->source->clone(this->source);
|
||||
}
|
||||
else
|
||||
{
|
||||
other->source = NULL;
|
||||
}
|
||||
|
||||
/* only clone existing chunks :-) */
|
||||
if (this->data.ptr != NULL)
|
||||
{
|
||||
other->data.ptr = clalloc(this->data.ptr,this->data.len);
|
||||
other->data.len = this->data.len;
|
||||
}
|
||||
else
|
||||
{
|
||||
other->data = CHUNK_INITIALIZER;
|
||||
}
|
||||
return &(other->public);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Documented in header
|
||||
*/
|
||||
packet_t *packet_create()
|
||||
{
|
||||
private_packet_t *this = malloc_thing(private_packet_t);
|
||||
|
||||
this->public.set_data = (void(*) (packet_t *,chunk_t)) set_data;
|
||||
this->public.get_data = (chunk_t(*) (packet_t *)) get_data;
|
||||
this->public.set_source = (void(*) (packet_t *,host_t*)) set_source;
|
||||
this->public.get_source = (host_t*(*) (packet_t *)) get_source;
|
||||
this->public.set_destination = (void(*) (packet_t *,host_t*)) set_destination;
|
||||
this->public.get_destination = (host_t*(*) (packet_t *)) get_destination;
|
||||
this->public.clone = (packet_t*(*) (packet_t *))clone;
|
||||
this->public.destroy = (void(*) (packet_t *)) destroy;
|
||||
|
||||
this->destination = NULL;
|
||||
this->source = NULL;
|
||||
this->data = CHUNK_INITIALIZER;
|
||||
|
||||
return &(this->public);
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
/**
|
||||
* @file packet.h
|
||||
*
|
||||
* @brief Interface of packet_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef PACKET_H_
|
||||
#define PACKET_H_
|
||||
|
||||
|
||||
#include <types.h>
|
||||
#include <utils/host.h>
|
||||
|
||||
|
||||
typedef struct packet_t packet_t;
|
||||
|
||||
/**
|
||||
* @brief Abstraction of an UDP-Packet, contains data, sender and receiver.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - packet_create()
|
||||
*
|
||||
* @ingroup network
|
||||
*/
|
||||
struct packet_t {
|
||||
|
||||
/**
|
||||
* @brief Set the source address.
|
||||
*
|
||||
* Set host_t is now owned by packet_t, it will destroy
|
||||
* it if necessary.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param source address to set as source
|
||||
*/
|
||||
void (*set_source) (packet_t *packet, host_t *source);
|
||||
|
||||
/**
|
||||
* @brief Set the destination address.
|
||||
*
|
||||
* Set host_t is now owned by packet_t, it will destroy
|
||||
* it if necessary.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param source address to set as destination
|
||||
*/
|
||||
void (*set_destination) (packet_t *packet, host_t *destination);
|
||||
|
||||
/**
|
||||
* @brief Get the source address.
|
||||
*
|
||||
* Set host_t is still owned by packet_t, clone it
|
||||
* if needed.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return source address
|
||||
*/
|
||||
host_t *(*get_source) (packet_t *packet);
|
||||
|
||||
/**
|
||||
* @brief Get the destination address.
|
||||
*
|
||||
* Set host_t is still owned by packet_t, clone it
|
||||
* if needed.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return destination address
|
||||
*/
|
||||
host_t *(*get_destination) (packet_t *packet);
|
||||
|
||||
/**
|
||||
* @brief Get the data from the packet.
|
||||
*
|
||||
* The data pointed by the chunk is still owned
|
||||
* by the packet. Clone it if needed.
|
||||
*
|
||||
* @param this calling object
|
||||
* @return chunk containing the data
|
||||
*/
|
||||
chunk_t (*get_data) (packet_t *packet);
|
||||
|
||||
/**
|
||||
* @brief Set the data in the packet.
|
||||
*
|
||||
* Supplied chunk data is now owned by the
|
||||
* packet. It will free it.
|
||||
*
|
||||
* @param this calling object
|
||||
* @param data chunk with data to set
|
||||
*/
|
||||
void (*set_data) (packet_t *packet, chunk_t data);
|
||||
|
||||
/**
|
||||
* @brief Clones a packet_t object.
|
||||
*
|
||||
* @param packet calling object
|
||||
* @param clone pointer to a packet_t object pointer where the new object is stored
|
||||
*/
|
||||
packet_t* (*clone) (packet_t *packet);
|
||||
|
||||
/**
|
||||
* @brief Destroy the packet, freeing contained data.
|
||||
*
|
||||
* @param packet packet to destroy
|
||||
*/
|
||||
void (*destroy) (packet_t *packet);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief create an empty packet
|
||||
*
|
||||
* @return packet_t object
|
||||
*
|
||||
* @ingroup network
|
||||
*/
|
||||
packet_t *packet_create();
|
||||
|
||||
|
||||
#endif /*PACKET_H_*/
|
||||
@@ -0,0 +1,457 @@
|
||||
/**
|
||||
* @file socket.c
|
||||
*
|
||||
* @brief Implementation of socket_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
* Copyright (C) 1998-2002 D. Hugh Redelmeier.
|
||||
* Copyright (C) 1997 Angelos D. Keromytis.
|
||||
*
|
||||
* Some parts of interface lookup code from pluto.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <pthread.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <net/if.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <linux/filter.h>
|
||||
|
||||
#include "socket.h"
|
||||
|
||||
#include <daemon.h>
|
||||
#include <utils/logger_manager.h>
|
||||
|
||||
|
||||
#define IP_HEADER_LENGTH 20
|
||||
#define UDP_HEADER_LENGTH 8
|
||||
|
||||
|
||||
/**
|
||||
* This filter code filters out all non-IKEv2 traffic on
|
||||
* a SOCK_RAW IP_PROTP_UDP socket. Handling of other
|
||||
* IKE versions is done in pluto.
|
||||
*/
|
||||
struct sock_filter ikev2_filter_code[] =
|
||||
{
|
||||
/* Protocol must be UDP */
|
||||
BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 9),
|
||||
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, IPPROTO_UDP, 0, 7),
|
||||
/* Destination Port must be 500 */
|
||||
BPF_STMT(BPF_LD+BPF_H+BPF_ABS, 22),
|
||||
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 500, 0, 5),
|
||||
/* IKE version must be 2.0 */
|
||||
BPF_STMT(BPF_LD+BPF_B+BPF_ABS, 45),
|
||||
BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, 0x20, 0, 3),
|
||||
/* packet length is length in IKEv2 header + ip header + udp header */
|
||||
BPF_STMT(BPF_LD+BPF_W+BPF_ABS, 52),
|
||||
BPF_STMT(BPF_ALU+BPF_ADD+BPF_K, IP_HEADER_LENGTH + UDP_HEADER_LENGTH),
|
||||
BPF_STMT(BPF_RET+BPF_A, 0),
|
||||
/* packet doesn't match IKEv2, ignore */
|
||||
BPF_STMT(BPF_RET+BPF_K, 0),
|
||||
};
|
||||
|
||||
/**
|
||||
* Filter struct to use with setsockopt
|
||||
*/
|
||||
struct sock_fprog ikev2_filter = {
|
||||
sizeof(ikev2_filter_code) / sizeof(struct sock_filter),
|
||||
ikev2_filter_code
|
||||
};
|
||||
|
||||
|
||||
typedef struct interface_t interface_t;
|
||||
|
||||
/**
|
||||
* An interface on which we listen.
|
||||
*/
|
||||
struct interface_t {
|
||||
|
||||
/**
|
||||
* Name of the interface
|
||||
*/
|
||||
char name[IFNAMSIZ];
|
||||
|
||||
/**
|
||||
* Associated socket
|
||||
*/
|
||||
int socket_fd;
|
||||
|
||||
/**
|
||||
* Host with listening address
|
||||
*/
|
||||
host_t *address;
|
||||
};
|
||||
|
||||
typedef struct private_socket_t private_socket_t;
|
||||
|
||||
/**
|
||||
* Private data of an socket_t object
|
||||
*/
|
||||
struct private_socket_t{
|
||||
/**
|
||||
* public functions
|
||||
*/
|
||||
socket_t public;
|
||||
|
||||
/**
|
||||
* Master socket
|
||||
*/
|
||||
int master_fd;
|
||||
|
||||
/**
|
||||
* List of all socket to listen
|
||||
*/
|
||||
linked_list_t* interfaces;
|
||||
|
||||
/**
|
||||
* logger for this socket
|
||||
*/
|
||||
logger_t *logger;
|
||||
};
|
||||
|
||||
/**
|
||||
* implementation of socket_t.receive
|
||||
*/
|
||||
static status_t receiver(private_socket_t *this, packet_t **packet)
|
||||
{
|
||||
char buffer[MAX_PACKET];
|
||||
chunk_t data;
|
||||
packet_t *pkt = packet_create();
|
||||
host_t *source, *dest;
|
||||
int bytes_read = 0;
|
||||
|
||||
|
||||
while (bytes_read >= 0)
|
||||
{
|
||||
int max_fd = 1;
|
||||
fd_set readfds;
|
||||
iterator_t *iterator;
|
||||
int oldstate;
|
||||
interface_t *interface;
|
||||
|
||||
/* build fd_set */
|
||||
FD_ZERO(&readfds);
|
||||
iterator = this->interfaces->create_iterator(this->interfaces, TRUE);
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
iterator->current(iterator, (void**)&interface);
|
||||
FD_SET(interface->socket_fd, &readfds);
|
||||
if (interface->socket_fd > max_fd)
|
||||
{
|
||||
max_fd = interface->socket_fd + 1;
|
||||
}
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
/* add packet destroy handler for cancellation, enable cancellation */
|
||||
pthread_cleanup_push((void(*)(void*))pkt->destroy, (void*)pkt);
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
|
||||
|
||||
this->logger->log(this->logger, CONTROL|LEVEL1, "waiting on sockets");
|
||||
bytes_read = select(max_fd, &readfds, NULL, NULL, NULL);
|
||||
|
||||
/* reset cancellation, remove packet destroy handler (without executing) */
|
||||
pthread_setcancelstate(oldstate, NULL);
|
||||
pthread_cleanup_pop(0);
|
||||
|
||||
/* read on the first nonblocking socket */
|
||||
bytes_read = 0;
|
||||
iterator = this->interfaces->create_iterator(this->interfaces, TRUE);
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
iterator->current(iterator, (void**)&interface);
|
||||
if (FD_ISSET(interface->socket_fd, &readfds))
|
||||
{
|
||||
/* do the read */
|
||||
bytes_read = recv(interface->socket_fd, buffer, MAX_PACKET, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
if (bytes_read < 0)
|
||||
{
|
||||
this->logger->log(this->logger, ERROR, "error reading from socket: %s", strerror(errno));
|
||||
continue;
|
||||
}
|
||||
if (bytes_read > IP_HEADER_LENGTH + UDP_HEADER_LENGTH)
|
||||
{
|
||||
/* read source/dest from raw IP/UDP header */
|
||||
chunk_t source_chunk = {buffer + 12, 4};
|
||||
chunk_t dest_chunk = {buffer + 16, 4};
|
||||
u_int16_t source_port = ntohs(*(u_int16_t*)(buffer + 20));
|
||||
u_int16_t dest_port = ntohs(*(u_int16_t*)(buffer + 22));
|
||||
source = host_create_from_chunk(AF_INET, source_chunk, source_port);
|
||||
dest = host_create_from_chunk(AF_INET, dest_chunk, dest_port);
|
||||
pkt->set_source(pkt, source);
|
||||
pkt->set_destination(pkt, dest);
|
||||
break;
|
||||
}
|
||||
this->logger->log(this->logger, ERROR|LEVEL1, "too short packet received");
|
||||
}
|
||||
|
||||
this->logger->log(this->logger, CONTROL, "received packet: from %s:%d to %s:%d",
|
||||
source->get_address(source), source->get_port(source),
|
||||
dest->get_address(dest), dest->get_port(dest));
|
||||
|
||||
/* fill in packet */
|
||||
data.len = bytes_read - IP_HEADER_LENGTH - UDP_HEADER_LENGTH;
|
||||
data.ptr = malloc(data.len);
|
||||
memcpy(data.ptr, buffer + IP_HEADER_LENGTH + UDP_HEADER_LENGTH, data.len);
|
||||
pkt->set_data(pkt, data);
|
||||
|
||||
/* return packet */
|
||||
*packet = pkt;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* implementation of socket_t.send
|
||||
*/
|
||||
status_t sender(private_socket_t *this, packet_t *packet)
|
||||
{
|
||||
ssize_t bytes_sent;
|
||||
chunk_t data;
|
||||
host_t *src, *dst;
|
||||
|
||||
src = packet->get_source(packet);
|
||||
dst = packet->get_destination(packet);
|
||||
data = packet->get_data(packet);
|
||||
|
||||
this->logger->log(this->logger, CONTROL, "sending packet: from %s:%d to %s:%d",
|
||||
src->get_address(src), src->get_port(src),
|
||||
dst->get_address(dst), dst->get_port(dst));
|
||||
|
||||
/* send data */
|
||||
/* TODO: should we send via the interface we received the packet? */
|
||||
bytes_sent = sendto(this->master_fd, data.ptr, data.len, 0,
|
||||
dst->get_sockaddr(dst), *(dst->get_sockaddr_len(dst)));
|
||||
|
||||
if (bytes_sent != data.len)
|
||||
{
|
||||
this->logger->log(this->logger, ERROR, "error writing to socket: %s", strerror(errno));
|
||||
return FAILED;
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all suitable interfaces, bind them and add them to the list
|
||||
*/
|
||||
static status_t build_interface_list(private_socket_t *this, u_int16_t port)
|
||||
{
|
||||
int on = TRUE;
|
||||
int i;
|
||||
struct sockaddr_in addr;
|
||||
struct ifconf ifconf;
|
||||
struct ifreq buf[300];
|
||||
|
||||
/* master socket for querying socket for a specific interfaces */
|
||||
this->master_fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (this->master_fd == -1)
|
||||
{
|
||||
this->logger->log(this->logger, ERROR, "could not open IPv4 master socket!");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
/* allow binding of multiplo sockets */
|
||||
if (setsockopt(this->master_fd, SOL_SOCKET, SO_REUSEADDR, (void*)&on, sizeof(on)) < 0)
|
||||
{
|
||||
this->logger->log(this->logger, ERROR, "unable to set SO_REUSEADDR on master socket!");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
/* bind the master socket */
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = INADDR_ANY;
|
||||
addr.sin_port = htons(port);
|
||||
if (bind(this->master_fd,(struct sockaddr*)&addr, sizeof(addr)) < 0)
|
||||
{
|
||||
this->logger->log(this->logger, ERROR, "unable to bind master socket: %s!", strerror(errno));
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
/* get all interfaces */
|
||||
ifconf.ifc_len = sizeof(buf);
|
||||
ifconf.ifc_buf = (void*) buf;
|
||||
memset(buf, 0, sizeof(buf));
|
||||
if (ioctl(this->master_fd, SIOCGIFCONF, &ifconf) == -1)
|
||||
{
|
||||
this->logger->log(this->logger, ERROR, "unable to get interfaces!");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
/* add every interesting interfaces to our interface list */
|
||||
for (i = 0; (i+1) * sizeof(*buf) <= (size_t)ifconf.ifc_len; i++)
|
||||
{
|
||||
struct sockaddr_in *current = (struct sockaddr_in*) &buf[i].ifr_addr;
|
||||
struct ifreq auxinfo;
|
||||
int skt;
|
||||
interface_t *interface;
|
||||
|
||||
if (current->sin_family != AF_INET)
|
||||
{
|
||||
/* ignore all but AF_INET interfaces */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* get auxilary info about socket */
|
||||
memset(&auxinfo, 0, sizeof(auxinfo));
|
||||
memcpy(auxinfo.ifr_name, buf[i].ifr_name, IFNAMSIZ);
|
||||
if (ioctl(this->master_fd, SIOCGIFFLAGS, &auxinfo) == -1)
|
||||
{
|
||||
this->logger->log(this->logger, ERROR, "unable to SIOCGIFFLAGS master socket!");
|
||||
continue;
|
||||
}
|
||||
if (!(auxinfo.ifr_flags & IFF_UP))
|
||||
{
|
||||
/* ignore an interface that isn't up */
|
||||
continue;
|
||||
}
|
||||
if (current->sin_addr.s_addr == 0)
|
||||
{
|
||||
/* ignore unconfigured interfaces */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* set up interface socket */
|
||||
skt = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
|
||||
if (socket < 0)
|
||||
{
|
||||
this->logger->log(this->logger, ERROR, "unable to open interface socket!");
|
||||
continue;
|
||||
}
|
||||
if (setsockopt(skt, SOL_SOCKET, SO_REUSEADDR, (void*)&on, sizeof(on)) < 0)
|
||||
{
|
||||
this->logger->log(this->logger, ERROR, "unable to set SO_REUSEADDR on interface socket!");
|
||||
close(skt);
|
||||
continue;
|
||||
}
|
||||
current->sin_port = htons(port);
|
||||
current->sin_family = AF_INET;
|
||||
if (bind(skt, (struct sockaddr*)current, sizeof(struct sockaddr_in)) < 0)
|
||||
{
|
||||
this->logger->log(this->logger, ERROR, "unable to bind interface socket!");
|
||||
close(skt);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (setsockopt(skt, SOL_SOCKET, SO_ATTACH_FILTER, &ikev2_filter, sizeof(ikev2_filter)) < 0)
|
||||
{
|
||||
this->logger->log(this->logger, ERROR, "unable to attack IKEv2 filter to interface socket!");
|
||||
close(skt);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* add socket with interface name to list */
|
||||
interface = malloc_thing(interface_t);
|
||||
memcpy(interface->name, buf[i].ifr_name, IFNAMSIZ);
|
||||
interface->name[IFNAMSIZ-1] = '\0';
|
||||
interface->socket_fd = skt;
|
||||
interface->address = host_create_from_sockaddr((struct sockaddr*)current);
|
||||
this->logger->log(this->logger, CONTROL, "listening on %s (%s)",
|
||||
interface->name, interface->address->get_address(interface->address));
|
||||
this->interfaces->insert_last(this->interfaces, (void*)interface);
|
||||
}
|
||||
|
||||
if (this->interfaces->get_count(this->interfaces) == 0)
|
||||
{
|
||||
this->logger->log(this->logger, ERROR, "unable to find any usable interface!");
|
||||
return FAILED;
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* implementation of socket_t.is_listening_on
|
||||
*/
|
||||
static bool is_listening_on(private_socket_t *this, host_t *host)
|
||||
{
|
||||
iterator_t *iterator;
|
||||
|
||||
/* listening on 0.0.0.0 is always TRUE */
|
||||
if (host->is_default_route(host))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* compare host with all interfaces */
|
||||
iterator = this->interfaces->create_iterator(this->interfaces, TRUE);
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
interface_t *interface;
|
||||
iterator->current(iterator, (void**)&interface);
|
||||
if (host->equals(host, interface->address))
|
||||
{
|
||||
iterator->destroy(iterator);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* implementation of socket_t.destroy
|
||||
*/
|
||||
static void destroy(private_socket_t *this)
|
||||
{
|
||||
interface_t *interface;
|
||||
while (this->interfaces->remove_last(this->interfaces, (void**)&interface) == SUCCESS)
|
||||
{
|
||||
interface->address->destroy(interface->address);
|
||||
close(interface->socket_fd);
|
||||
free(interface);
|
||||
}
|
||||
this->interfaces->destroy(this->interfaces);
|
||||
close(this->master_fd);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* See header for description
|
||||
*/
|
||||
socket_t *socket_create(u_int16_t port)
|
||||
{
|
||||
private_socket_t *this = malloc_thing(private_socket_t);
|
||||
|
||||
/* public functions */
|
||||
this->public.send = (status_t(*)(socket_t*, packet_t*))sender;
|
||||
this->public.receive = (status_t(*)(socket_t*, packet_t**))receiver;
|
||||
this->public.is_listening_on = (bool (*)(socket_t*,host_t*))is_listening_on;
|
||||
this->public.destroy = (void(*)(socket_t*)) destroy;
|
||||
|
||||
this->logger = logger_manager->get_logger(logger_manager, SOCKET);
|
||||
this->interfaces = linked_list_create();
|
||||
|
||||
if (build_interface_list(this, port) != SUCCESS)
|
||||
{
|
||||
this->interfaces->destroy(this->interfaces);
|
||||
free(this);
|
||||
charon->kill(charon, "could not bind any interface!");
|
||||
}
|
||||
|
||||
return (socket_t*)this;
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
/**
|
||||
* @file socket.h
|
||||
*
|
||||
* @brief Interface for socket_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef SOCKET_H_
|
||||
#define SOCKET_H_
|
||||
|
||||
|
||||
#include <types.h>
|
||||
#include <network/packet.h>
|
||||
|
||||
|
||||
/**
|
||||
* @brief Maximum size of a packet.
|
||||
*
|
||||
* 3000 Bytes should be sufficient, see IKEv2 RFC.
|
||||
*
|
||||
* @ingroup network
|
||||
*/
|
||||
#define MAX_PACKET 3000
|
||||
|
||||
|
||||
typedef struct socket_t socket_t;
|
||||
|
||||
/**
|
||||
* @brief Abstraction all sockets (currently IPv4 only).
|
||||
*
|
||||
* All available IPv4 sockets are bound and the receive function
|
||||
* reads from them. To allow binding of other daemons (pluto) to
|
||||
* UDP/500, this implementation uses RAW sockets. An installed
|
||||
* "Linux socket filter" filters out all non-IKEv2 traffic and handles
|
||||
* just IKEv2 messages. An other daemon (pluto) must handle all traffic
|
||||
* seperatly, e.g. ignore IKEv2 traffic, since charon handles that.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - socket_create()
|
||||
*
|
||||
* @todo add IPv6 support
|
||||
*
|
||||
* @todo We currently use multiple sockets for historic reasons. With the
|
||||
* new RAW socket mechanism, we could use just one socket and filter
|
||||
* addresses in userspace (or via linux socket filter). This would allow
|
||||
* realtime interface/address management in a easy way...
|
||||
*
|
||||
* @ingroup network
|
||||
*/
|
||||
struct socket_t {
|
||||
/**
|
||||
* @brief Receive a packet.
|
||||
*
|
||||
* Reads a packet from the socket and sets source/dest
|
||||
* appropriately.
|
||||
*
|
||||
* @param sock socket_t object to work on
|
||||
* @param packet pinter gets address from allocated packet_t
|
||||
* @return
|
||||
* - SUCCESS when packet successfully received
|
||||
* - FAILED when unable to receive
|
||||
*/
|
||||
status_t (*receive) (socket_t *sock, packet_t **packet);
|
||||
|
||||
/**
|
||||
* @brief Send a packet.
|
||||
*
|
||||
* Sends a packet to the net using destination from the packet.
|
||||
* Packet is sent using default routing mechanisms, thus the
|
||||
* source address in packet is ignored.
|
||||
*
|
||||
* @param sock socket_t object to work on
|
||||
* @param packet[out] packet_t to send
|
||||
* @return
|
||||
* - SUCCESS when packet successfully sent
|
||||
* - FAILED when unable to send
|
||||
*/
|
||||
status_t (*send) (socket_t *sock, packet_t *packet);
|
||||
|
||||
/**
|
||||
* @brief Check if socket listens on an address.
|
||||
*
|
||||
* @param sock socket_t object to work on
|
||||
* @param host address to check
|
||||
* @return TRUE if listening on host, FALSE otherwise
|
||||
*/
|
||||
bool (*is_listening_on) (socket_t *sock, host_t *host);
|
||||
|
||||
/**
|
||||
* @brief Destroy sockets.
|
||||
*
|
||||
* close sockets and destroy socket_t object
|
||||
*
|
||||
* @param sock socket_t to destroy
|
||||
*/
|
||||
void (*destroy) (socket_t *sock);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Create a socket_t, wich binds multiple sockets.
|
||||
*
|
||||
* currently creates one socket, listening on all addresses
|
||||
* on "port".
|
||||
*
|
||||
* @param port port to bind socket to
|
||||
* @return socket_t object
|
||||
*
|
||||
* @ingroup network
|
||||
*/
|
||||
socket_t *socket_create(u_int16_t port);
|
||||
|
||||
|
||||
#endif /*SOCKET_H_*/
|
||||
@@ -0,0 +1,30 @@
|
||||
# Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
# Hochschule fuer Technik Rapperswil
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the
|
||||
# Free Software Foundation; either version 2 of the License, or (at your
|
||||
# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# for more details.
|
||||
#
|
||||
|
||||
QUEUES_DIR= $(CHARON_DIR)queues/
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)event_queue.o
|
||||
$(BUILD_DIR)event_queue.o : $(QUEUES_DIR)event_queue.c $(QUEUES_DIR)event_queue.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)job_queue.o
|
||||
$(BUILD_DIR)job_queue.o : $(QUEUES_DIR)job_queue.c $(QUEUES_DIR)job_queue.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)send_queue.o
|
||||
$(BUILD_DIR)send_queue.o : $(QUEUES_DIR)send_queue.c $(QUEUES_DIR)send_queue.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
|
||||
include $(QUEUES_DIR)jobs/Makefile.jobs
|
||||
@@ -0,0 +1,349 @@
|
||||
/**
|
||||
* @file event_queue.c
|
||||
*
|
||||
* @brief Implementation of event_queue_t
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "event_queue.h"
|
||||
|
||||
#include <types.h>
|
||||
#include <utils/linked_list.h>
|
||||
|
||||
|
||||
|
||||
typedef struct event_t event_t;
|
||||
|
||||
/**
|
||||
* @brief Represents an event as it is stored in the event queue.
|
||||
*
|
||||
* A event consists of a event time and an assigned job object.
|
||||
*
|
||||
*/
|
||||
struct event_t{
|
||||
/**
|
||||
* Time to fire the event.
|
||||
*/
|
||||
timeval_t time;
|
||||
|
||||
/**
|
||||
* Every event has its assigned job.
|
||||
*/
|
||||
job_t * job;
|
||||
|
||||
/**
|
||||
* @brief Destroys a event_t object.
|
||||
*
|
||||
* @param event_t calling object
|
||||
*/
|
||||
void (*destroy) (event_t *event);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* implements event_t.destroy
|
||||
*/
|
||||
static void event_destroy(event_t *event)
|
||||
{
|
||||
free(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates a event for a specific time
|
||||
*
|
||||
* @param time absolute time to fire the event
|
||||
* @param job job to add to job-queue at specific time
|
||||
*
|
||||
* @returns created event_t object
|
||||
*/
|
||||
static event_t *event_create(timeval_t time, job_t *job)
|
||||
{
|
||||
event_t *this = malloc_thing(event_t);
|
||||
|
||||
this->destroy = event_destroy;
|
||||
this->time = time;
|
||||
this->job = job;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
typedef struct private_event_queue_t private_event_queue_t;
|
||||
|
||||
/**
|
||||
* Private Variables and Functions of event_queue_t class.
|
||||
*
|
||||
*/
|
||||
struct private_event_queue_t {
|
||||
/**
|
||||
* Public part.
|
||||
*/
|
||||
event_queue_t public;
|
||||
|
||||
/**
|
||||
* The events are stored in a linked list of type linked_list_t.
|
||||
*/
|
||||
linked_list_t *list;
|
||||
|
||||
/**
|
||||
* Access to linked_list is locked through this mutex.
|
||||
*/
|
||||
pthread_mutex_t mutex;
|
||||
|
||||
/**
|
||||
* If the queue is empty or an event has not to be fired
|
||||
* a thread has to wait.
|
||||
*
|
||||
* This condvar is used to wake up such a thread.
|
||||
*/
|
||||
pthread_cond_t condvar;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the difference of to timeval structs in microseconds
|
||||
*
|
||||
* @param end_time end time
|
||||
* @param start_time start time
|
||||
*
|
||||
* @warning this function is also defined in the tester class
|
||||
* In later improvements, this function can be added to a general
|
||||
* class type!
|
||||
*
|
||||
* @return difference in microseconds (end time - start time)
|
||||
*/
|
||||
static long time_difference(struct timeval *end_time, struct timeval *start_time)
|
||||
{
|
||||
long seconds, microseconds;
|
||||
|
||||
seconds = (end_time->tv_sec - start_time->tv_sec);
|
||||
microseconds = (end_time->tv_usec - start_time->tv_usec);
|
||||
return ((seconds * 1000000) + microseconds);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implements event_queue_t.get_count
|
||||
*/
|
||||
static int get_count (private_event_queue_t *this)
|
||||
{
|
||||
int count;
|
||||
pthread_mutex_lock(&(this->mutex));
|
||||
count = this->list->get_count(this->list);
|
||||
pthread_mutex_unlock(&(this->mutex));
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements event_queue_t.get
|
||||
*/
|
||||
static job_t *get(private_event_queue_t *this)
|
||||
{
|
||||
timespec_t timeout;
|
||||
timeval_t current_time;
|
||||
event_t * next_event;
|
||||
job_t *job;
|
||||
int oldstate;
|
||||
|
||||
pthread_mutex_lock(&(this->mutex));
|
||||
|
||||
while (1)
|
||||
{
|
||||
while(this->list->get_count(this->list) == 0)
|
||||
{
|
||||
/* add mutex unlock handler for cancellation, enable cancellation */
|
||||
pthread_cleanup_push((void(*)(void*))pthread_mutex_unlock, (void*)&(this->mutex));
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
|
||||
|
||||
pthread_cond_wait( &(this->condvar), &(this->mutex));
|
||||
|
||||
/* reset cancellation, remove mutex-unlock handler (without executing) */
|
||||
pthread_setcancelstate(oldstate, NULL);
|
||||
pthread_cleanup_pop(0);
|
||||
}
|
||||
|
||||
this->list->get_first(this->list,(void **) &next_event);
|
||||
|
||||
gettimeofday(¤t_time,NULL);
|
||||
long difference = time_difference(¤t_time,&(next_event->time));
|
||||
if (difference <= 0)
|
||||
{
|
||||
timeout.tv_sec = next_event->time.tv_sec;
|
||||
timeout.tv_nsec = next_event->time.tv_usec * 1000;
|
||||
|
||||
/* add mutex unlock handler for cancellation, enable cancellation */
|
||||
pthread_cleanup_push((void(*)(void*))pthread_mutex_unlock, (void*)&(this->mutex));
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
|
||||
|
||||
pthread_cond_timedwait( &(this->condvar), &(this->mutex),&timeout);
|
||||
|
||||
/* reset cancellation, remove mutex-unlock handler (without executing) */
|
||||
pthread_setcancelstate(oldstate, NULL);
|
||||
pthread_cleanup_pop(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* event available */
|
||||
this->list->remove_first(this->list,(void **) &next_event);
|
||||
|
||||
job = next_event->job;
|
||||
|
||||
next_event->destroy(next_event);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
pthread_cond_signal( &(this->condvar));
|
||||
|
||||
pthread_mutex_unlock(&(this->mutex));
|
||||
|
||||
return job;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements function add_absolute of event_queue_t.
|
||||
* See #event_queue_s.add_absolute for description.
|
||||
*/
|
||||
static void add_absolute(private_event_queue_t *this, job_t *job, timeval_t time)
|
||||
{
|
||||
event_t *event = event_create(time,job);
|
||||
event_t *current_event;
|
||||
status_t status;
|
||||
|
||||
pthread_mutex_lock(&(this->mutex));
|
||||
|
||||
/* while just used to break out */
|
||||
while(1)
|
||||
{
|
||||
if (this->list->get_count(this->list) == 0)
|
||||
{
|
||||
this->list->insert_first(this->list,event);
|
||||
break;
|
||||
}
|
||||
|
||||
/* check last entry */
|
||||
this->list->get_last(this->list,(void **) ¤t_event);
|
||||
|
||||
if (time_difference(&(event->time), &(current_event->time)) >= 0)
|
||||
{
|
||||
/* my event has to be fired after the last event in list */
|
||||
this->list->insert_last(this->list,event);
|
||||
break;
|
||||
}
|
||||
|
||||
/* check first entry */
|
||||
this->list->get_first(this->list,(void **) ¤t_event);
|
||||
|
||||
if (time_difference(&(event->time), &(current_event->time)) < 0)
|
||||
{
|
||||
/* my event has to be fired before the first event in list */
|
||||
this->list->insert_first(this->list,event);
|
||||
break;
|
||||
}
|
||||
|
||||
iterator_t * iterator;
|
||||
|
||||
iterator = this->list->create_iterator(this->list,TRUE);
|
||||
|
||||
iterator->has_next(iterator);
|
||||
/* first element has not to be checked (already done) */
|
||||
|
||||
while(iterator->has_next(iterator))
|
||||
{
|
||||
status = iterator->current(iterator,(void **) ¤t_event);
|
||||
|
||||
if (time_difference(&(event->time), &(current_event->time)) <= 0)
|
||||
{
|
||||
/* my event has to be fired before the current event in list */
|
||||
iterator->insert_before(iterator,event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
break;
|
||||
}
|
||||
|
||||
pthread_cond_signal( &(this->condvar));
|
||||
pthread_mutex_unlock(&(this->mutex));
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements event_queue_t.add_relative.
|
||||
*/
|
||||
static void add_relative(event_queue_t *this, job_t *job, u_int32_t ms)
|
||||
{
|
||||
timeval_t current_time;
|
||||
timeval_t time;
|
||||
int micros = ms * 1000;
|
||||
|
||||
gettimeofday(¤t_time, NULL);
|
||||
|
||||
time.tv_usec = ((current_time.tv_usec + micros) % 1000000);
|
||||
time.tv_sec = current_time.tv_sec + ((current_time.tv_usec + micros)/ 1000000);
|
||||
|
||||
this->add_absolute(this, job, time);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Implements event_queue_t.destroy.
|
||||
*/
|
||||
static void event_queue_destroy(private_event_queue_t *this)
|
||||
{
|
||||
while (this->list->get_count(this->list) > 0)
|
||||
{
|
||||
event_t *event;
|
||||
|
||||
if (this->list->remove_first(this->list,(void *) &event) != SUCCESS)
|
||||
{
|
||||
this->list->destroy(this->list);
|
||||
break;
|
||||
}
|
||||
event->job->destroy_all(event->job);
|
||||
event->destroy(event);
|
||||
}
|
||||
this->list->destroy(this->list);
|
||||
|
||||
pthread_mutex_destroy(&(this->mutex));
|
||||
|
||||
pthread_cond_destroy(&(this->condvar));
|
||||
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Documented in header
|
||||
*/
|
||||
event_queue_t *event_queue_create()
|
||||
{
|
||||
private_event_queue_t *this = malloc_thing(private_event_queue_t);
|
||||
|
||||
this->public.get_count = (int (*) (event_queue_t *event_queue)) get_count;
|
||||
this->public.get = (job_t *(*) (event_queue_t *event_queue)) get;
|
||||
this->public.add_absolute = (void (*) (event_queue_t *event_queue, job_t *job, timeval_t time)) add_absolute;
|
||||
this->public.add_relative = (void (*) (event_queue_t *event_queue, job_t *job, u_int32_t ms)) add_relative;
|
||||
this->public.destroy = (void (*) (event_queue_t *event_queue)) event_queue_destroy;
|
||||
|
||||
this->list = linked_list_create();
|
||||
pthread_mutex_init(&(this->mutex), NULL);
|
||||
pthread_cond_init(&(this->condvar), NULL);
|
||||
|
||||
return (&this->public);
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
/**
|
||||
* @file event_queue.h
|
||||
*
|
||||
* @brief Interface of job_queue_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef EVENT_QUEUE_H_
|
||||
#define EVENT_QUEUE_H_
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <types.h>
|
||||
#include <queues/jobs/job.h>
|
||||
|
||||
typedef struct event_queue_t event_queue_t;
|
||||
|
||||
/**
|
||||
* @brief Event-Queue used to store timed events.
|
||||
*
|
||||
* Added events are sorted. The get method blocks until
|
||||
* the time is elapsed to process the next event. The get
|
||||
* method is called from the scheduler_t thread, which
|
||||
* will add the jobs to to job_queue_t for further processing.
|
||||
*
|
||||
* Although the event-queue is based on a linked_list_t
|
||||
* all access functions are thread-save implemented.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - event_queue_create()
|
||||
*
|
||||
* @ingroup queues
|
||||
*/
|
||||
struct event_queue_t {
|
||||
|
||||
/**
|
||||
* @brief Returns number of events in queue.
|
||||
*
|
||||
* @param event_queue calling object
|
||||
* @return number of events in queue
|
||||
*/
|
||||
int (*get_count) (event_queue_t *event_queue);
|
||||
|
||||
/**
|
||||
* @brief Get the next job from the event-queue.
|
||||
*
|
||||
* If no event is pending, this function blocks until a job can be returned.
|
||||
*
|
||||
* @param event_queue calling object
|
||||
* @param[out] job pointer to a job pointer where to job is returned to
|
||||
* @return next job
|
||||
*/
|
||||
job_t *(*get) (event_queue_t *event_queue);
|
||||
|
||||
/**
|
||||
* @brief Adds a event to the queue, using a relative time.
|
||||
*
|
||||
* This function is non blocking and adds a job_t at a specific time to the list.
|
||||
* The specific job object has to get destroyed by the thread which
|
||||
* removes the job.
|
||||
*
|
||||
* @param event_queue calling object
|
||||
* @param[in] job job to add to the queue (job is not copied)
|
||||
* @param[in] time relative time, when the event has to get fired
|
||||
*/
|
||||
void (*add_relative) (event_queue_t *event_queue, job_t *job, u_int32_t ms);
|
||||
|
||||
/**
|
||||
* @brief Adds a event to the queue, using an absolute time.
|
||||
*
|
||||
* This function is non blocking and adds a job_t at a specific time to the list.
|
||||
* The specific job object has to get destroyed by the thread which
|
||||
* removes the job.
|
||||
*
|
||||
* @param event_queue calling object
|
||||
* @param[in] job job to add to the queue (job is not copied)
|
||||
* @param[in] absolute time time, when the event has to get fired
|
||||
*/
|
||||
void (*add_absolute) (event_queue_t *event_queue, job_t *job, timeval_t time);
|
||||
|
||||
/**
|
||||
* @brief Destroys a event_queue object.
|
||||
*
|
||||
* @warning The caller of this function has to make sure
|
||||
* that no thread is going to add or get an event from the event_queue
|
||||
* after calling this function.
|
||||
*
|
||||
* @param event_queue calling object
|
||||
*/
|
||||
void (*destroy) (event_queue_t *event_queue);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Creates an empty event_queue.
|
||||
*
|
||||
* @returns event_queue_t object
|
||||
*
|
||||
* @ingroup queues
|
||||
*/
|
||||
event_queue_t *event_queue_create();
|
||||
|
||||
#endif /*EVENT_QUEUE_H_*/
|
||||
@@ -0,0 +1,153 @@
|
||||
/**
|
||||
* @file job_queue.c
|
||||
*
|
||||
* @brief Implementation of job_queue_t
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "job_queue.h"
|
||||
|
||||
#include <utils/linked_list.h>
|
||||
|
||||
|
||||
typedef struct private_job_queue_t private_job_queue_t;
|
||||
|
||||
/**
|
||||
* @brief Private Variables and Functions of job_queue class
|
||||
*
|
||||
*/
|
||||
struct private_job_queue_t {
|
||||
|
||||
/**
|
||||
* public members
|
||||
*/
|
||||
job_queue_t public;
|
||||
|
||||
/**
|
||||
* The jobs are stored in a linked list
|
||||
*/
|
||||
linked_list_t *list;
|
||||
|
||||
/**
|
||||
* access to linked_list is locked through this mutex
|
||||
*/
|
||||
pthread_mutex_t mutex;
|
||||
|
||||
/**
|
||||
* If the queue is empty a thread has to wait
|
||||
* This condvar is used to wake up such a thread
|
||||
*/
|
||||
pthread_cond_t condvar;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* implements job_queue_t.get_count
|
||||
*/
|
||||
static int get_count(private_job_queue_t *this)
|
||||
{
|
||||
int count;
|
||||
pthread_mutex_lock(&(this->mutex));
|
||||
count = this->list->get_count(this->list);
|
||||
pthread_mutex_unlock(&(this->mutex));
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* implements job_queue_t.get
|
||||
*/
|
||||
static job_t *get(private_job_queue_t *this)
|
||||
{
|
||||
int oldstate;
|
||||
job_t *job;
|
||||
pthread_mutex_lock(&(this->mutex));
|
||||
/* go to wait while no jobs available */
|
||||
while(this->list->get_count(this->list) == 0)
|
||||
{
|
||||
/* add mutex unlock handler for cancellation, enable cancellation */
|
||||
pthread_cleanup_push((void(*)(void*))pthread_mutex_unlock, (void*)&(this->mutex));
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
|
||||
|
||||
pthread_cond_wait( &(this->condvar), &(this->mutex));
|
||||
|
||||
/* reset cancellation, remove mutex-unlock handler (without executing) */
|
||||
pthread_setcancelstate(oldstate, NULL);
|
||||
pthread_cleanup_pop(0);
|
||||
}
|
||||
this->list->remove_first(this->list,(void **) &job);
|
||||
pthread_mutex_unlock(&(this->mutex));
|
||||
return job;
|
||||
}
|
||||
|
||||
/**
|
||||
* implements function job_queue_t.add
|
||||
*/
|
||||
static void add(private_job_queue_t *this, job_t *job)
|
||||
{
|
||||
pthread_mutex_lock(&(this->mutex));
|
||||
this->list->insert_last(this->list,job);
|
||||
pthread_cond_signal( &(this->condvar));
|
||||
pthread_mutex_unlock(&(this->mutex));
|
||||
}
|
||||
|
||||
/**
|
||||
* implements job_queue_t.destroy
|
||||
*/
|
||||
static void job_queue_destroy (private_job_queue_t *this)
|
||||
{
|
||||
while (this->list->get_count(this->list) > 0)
|
||||
{
|
||||
job_t *job;
|
||||
if (this->list->remove_first(this->list,(void *) &job) != SUCCESS)
|
||||
{
|
||||
this->list->destroy(this->list);
|
||||
break;
|
||||
}
|
||||
job->destroy_all(job);
|
||||
}
|
||||
this->list->destroy(this->list);
|
||||
|
||||
pthread_mutex_destroy(&(this->mutex));
|
||||
|
||||
pthread_cond_destroy(&(this->condvar));
|
||||
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* Documented in header
|
||||
*/
|
||||
job_queue_t *job_queue_create()
|
||||
{
|
||||
private_job_queue_t *this = malloc_thing(private_job_queue_t);
|
||||
|
||||
this->public.get_count = (int(*)(job_queue_t*))get_count;
|
||||
this->public.get = (job_t*(*)(job_queue_t*))get;
|
||||
this->public.add = (void(*)(job_queue_t*, job_t*))add;
|
||||
this->public.destroy = (void(*)(job_queue_t*))job_queue_destroy;
|
||||
|
||||
this->list = linked_list_create();
|
||||
pthread_mutex_init(&(this->mutex), NULL);
|
||||
pthread_cond_init(&(this->condvar), NULL);
|
||||
|
||||
return (&this->public);
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/**
|
||||
* @file job_queue.h
|
||||
*
|
||||
* @brief Interface of job_queue_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef JOB_QUEUE_H_
|
||||
#define JOB_QUEUE_H_
|
||||
|
||||
#include <types.h>
|
||||
#include <queues/jobs/job.h>
|
||||
|
||||
typedef struct job_queue_t job_queue_t;
|
||||
|
||||
/**
|
||||
* @brief The job queue stores jobs, which will be processed by the thread_pool_t.
|
||||
*
|
||||
* Jobs are added from various sources, from the threads and
|
||||
* from the event_queue_t.
|
||||
* Although the job-queue is based on a linked_list_t
|
||||
* all access functions are thread-save implemented.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - job_queue_create()
|
||||
*
|
||||
* @ingroup queues
|
||||
*/
|
||||
struct job_queue_t {
|
||||
|
||||
/**
|
||||
* @brief Returns number of jobs in queue.
|
||||
*
|
||||
* @param job_queue_t calling object
|
||||
* @returns number of items in queue
|
||||
*/
|
||||
int (*get_count) (job_queue_t *job_queue);
|
||||
|
||||
/**
|
||||
* @brief Get the next job from the queue.
|
||||
*
|
||||
* If the queue is empty, this function blocks until a job can be returned.
|
||||
* After using, the returned job has to get destroyed by the caller.
|
||||
*
|
||||
* @param job_queue_t calling object
|
||||
* @param[out] job pointer to a job pointer where to job is returned to
|
||||
* @return next job
|
||||
*/
|
||||
job_t *(*get) (job_queue_t *job_queue);
|
||||
|
||||
/**
|
||||
* @brief Adds a job to the queue.
|
||||
*
|
||||
* This function is non blocking and adds a job_t to the list.
|
||||
* The specific job object has to get destroyed by the thread which
|
||||
* removes the job.
|
||||
*
|
||||
* @param job_queue_t calling object
|
||||
* @param job job to add to the queue (job is not copied)
|
||||
*/
|
||||
void (*add) (job_queue_t *job_queue, job_t *job);
|
||||
|
||||
/**
|
||||
* @brief Destroys a job_queue object.
|
||||
*
|
||||
* @warning The caller of this function has to make sure
|
||||
* that no thread is going to add or get a job from the job_queue
|
||||
* after calling this function.
|
||||
*
|
||||
* @param job_queue_t calling object
|
||||
*/
|
||||
void (*destroy) (job_queue_t *job_queue);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Creates an empty job_queue.
|
||||
*
|
||||
* @return job_queue_t object
|
||||
*
|
||||
* @ingroup queues
|
||||
*/
|
||||
job_queue_t *job_queue_create();
|
||||
|
||||
#endif /*JOB_QUEUE_H_*/
|
||||
@@ -0,0 +1,40 @@
|
||||
# Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
# Hochschule fuer Technik Rapperswil
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the
|
||||
# Free Software Foundation; either version 2 of the License, or (at your
|
||||
# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# for more details.
|
||||
#
|
||||
|
||||
JOBS_DIR= $(QUEUES_DIR)jobs/
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)delete_half_open_ike_sa_job.o
|
||||
$(BUILD_DIR)delete_half_open_ike_sa_job.o : $(JOBS_DIR)delete_half_open_ike_sa_job.c $(JOBS_DIR)delete_half_open_ike_sa_job.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)delete_established_ike_sa_job.o
|
||||
$(BUILD_DIR)delete_established_ike_sa_job.o : $(JOBS_DIR)delete_established_ike_sa_job.c $(JOBS_DIR)delete_established_ike_sa_job.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)incoming_packet_job.o
|
||||
$(BUILD_DIR)incoming_packet_job.o : $(JOBS_DIR)incoming_packet_job.c $(JOBS_DIR)incoming_packet_job.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)initiate_ike_sa_job.o
|
||||
$(BUILD_DIR)initiate_ike_sa_job.o : $(JOBS_DIR)initiate_ike_sa_job.c $(JOBS_DIR)initiate_ike_sa_job.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)retransmit_request_job.o
|
||||
$(BUILD_DIR)retransmit_request_job.o : $(JOBS_DIR)retransmit_request_job.c $(JOBS_DIR)retransmit_request_job.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
CHARON_OBJS+= $(BUILD_DIR)job.o
|
||||
$(BUILD_DIR)job.o : $(JOBS_DIR)job.c $(JOBS_DIR)job.h
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
* @file delete_established_ike_sa_job.c
|
||||
*
|
||||
* @brief Implementation of delete_established_ike_sa_job_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "delete_established_ike_sa_job.h"
|
||||
|
||||
|
||||
|
||||
typedef struct private_delete_established_ike_sa_job_t private_delete_established_ike_sa_job_t;
|
||||
|
||||
/**
|
||||
* Private data of an delete_established_ike_sa_job_t object.
|
||||
*/
|
||||
struct private_delete_established_ike_sa_job_t {
|
||||
/**
|
||||
* Public delete_established_ike_sa_job_t interface.
|
||||
*/
|
||||
delete_established_ike_sa_job_t public;
|
||||
|
||||
/**
|
||||
* ID of the ike_sa to delete.
|
||||
*/
|
||||
ike_sa_id_t *ike_sa_id;
|
||||
};
|
||||
|
||||
/**
|
||||
* Implementation of job_t.get_type.
|
||||
*/
|
||||
static job_type_t get_type(private_delete_established_ike_sa_job_t *this)
|
||||
{
|
||||
return DELETE_ESTABLISHED_IKE_SA;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of delete_established_ike_sa_job_t.get_ike_sa_id
|
||||
*/
|
||||
static ike_sa_id_t *get_ike_sa_id(private_delete_established_ike_sa_job_t *this)
|
||||
{
|
||||
return this->ike_sa_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of job_t.destroy.
|
||||
*/
|
||||
static void destroy(private_delete_established_ike_sa_job_t *this)
|
||||
{
|
||||
this->ike_sa_id->destroy(this->ike_sa_id);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
delete_established_ike_sa_job_t *delete_established_ike_sa_job_create(ike_sa_id_t *ike_sa_id)
|
||||
{
|
||||
private_delete_established_ike_sa_job_t *this = malloc_thing(private_delete_established_ike_sa_job_t);
|
||||
|
||||
/* interface functions */
|
||||
this->public.job_interface.get_type = (job_type_t (*) (job_t *)) get_type;
|
||||
/* same as destroy */
|
||||
this->public.job_interface.destroy_all = (void (*) (job_t *)) destroy;
|
||||
this->public.job_interface.destroy = (void (*)(job_t*)) destroy;
|
||||
|
||||
/* public functions */
|
||||
this->public.get_ike_sa_id = (ike_sa_id_t * (*)(delete_established_ike_sa_job_t *)) get_ike_sa_id;
|
||||
this->public.destroy = (void (*)(delete_established_ike_sa_job_t *)) destroy;
|
||||
|
||||
/* private variables */
|
||||
this->ike_sa_id = ike_sa_id->clone(ike_sa_id);
|
||||
|
||||
return &(this->public);
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* @file delete_established_ike_sa_job.h
|
||||
*
|
||||
* @brief Interface of delete_established_ike_sa_job_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef DELETE_ESTABLISHED_IKE_SA_JOB_H_
|
||||
#define DELETE_ESTABLISHED_IKE_SA_JOB_H_
|
||||
|
||||
#include <types.h>
|
||||
#include <sa/ike_sa_id.h>
|
||||
#include <queues/jobs/job.h>
|
||||
|
||||
|
||||
typedef struct delete_established_ike_sa_job_t delete_established_ike_sa_job_t;
|
||||
|
||||
/**
|
||||
* @brief Class representing an DELETE_ESTABLISHED_IKE_SA Job.
|
||||
*
|
||||
* This job initiates the deletion of an IKE_SA. The SA
|
||||
* to delete is specified via an ike_sa_id_t.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - delete_established_ike_sa_job_create()
|
||||
*
|
||||
* @ingroup jobs
|
||||
*/
|
||||
struct delete_established_ike_sa_job_t {
|
||||
/**
|
||||
* The job_t interface.
|
||||
*/
|
||||
job_t job_interface;
|
||||
|
||||
/**
|
||||
* @brief Returns the currently set ike_sa_id.
|
||||
*
|
||||
* @warning Returned object is not copied.
|
||||
*
|
||||
* @param this calling delete_established_ike_sa_job_t object
|
||||
* @return ike_sa_id_t object
|
||||
*/
|
||||
ike_sa_id_t * (*get_ike_sa_id) (delete_established_ike_sa_job_t *this);
|
||||
|
||||
/**
|
||||
* @brief Destroys an delete_established_ike_sa_job_t object (including assigned data).
|
||||
*
|
||||
* @param this delete_established_ike_sa_job_t object to destroy
|
||||
*/
|
||||
void (*destroy) (delete_established_ike_sa_job_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Creates a job of type DELETE_ESTABLISHED_IKE_SA.
|
||||
*
|
||||
* @param ike_sa_id id of the IKE_SA to delete
|
||||
* @return delete_established_ike_sa_job_t object
|
||||
*
|
||||
* @ingroup jobs
|
||||
*/
|
||||
delete_established_ike_sa_job_t *delete_established_ike_sa_job_create(ike_sa_id_t *ike_sa_id);
|
||||
|
||||
#endif /*DELETE_ESTABLISHED_IKE_SA_JOB_H_*/
|
||||
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
* @file delete_half_open_ike_sa_job.c
|
||||
*
|
||||
* @brief Implementation of delete_half_open_ike_sa_job_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "delete_half_open_ike_sa_job.h"
|
||||
|
||||
|
||||
|
||||
typedef struct private_delete_half_open_ike_sa_job_t private_delete_half_open_ike_sa_job_t;
|
||||
|
||||
/**
|
||||
* Private data of an delete_half_open_ike_sa_job_t Object
|
||||
*/
|
||||
struct private_delete_half_open_ike_sa_job_t {
|
||||
/**
|
||||
* public delete_half_open_ike_sa_job_t interface
|
||||
*/
|
||||
delete_half_open_ike_sa_job_t public;
|
||||
|
||||
/**
|
||||
* ID of the ike_sa to delete
|
||||
*/
|
||||
ike_sa_id_t *ike_sa_id;
|
||||
};
|
||||
|
||||
/**
|
||||
* Implements job_t.get_type.
|
||||
*/
|
||||
static job_type_t get_type(private_delete_half_open_ike_sa_job_t *this)
|
||||
{
|
||||
return DELETE_HALF_OPEN_IKE_SA;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements elete_ike_sa_job_t.get_ike_sa_id
|
||||
*/
|
||||
static ike_sa_id_t *get_ike_sa_id(private_delete_half_open_ike_sa_job_t *this)
|
||||
{
|
||||
return this->ike_sa_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements job_t.destroy.
|
||||
*/
|
||||
static void destroy(private_delete_half_open_ike_sa_job_t *this)
|
||||
{
|
||||
this->ike_sa_id->destroy(this->ike_sa_id);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
delete_half_open_ike_sa_job_t *delete_half_open_ike_sa_job_create(ike_sa_id_t *ike_sa_id)
|
||||
{
|
||||
private_delete_half_open_ike_sa_job_t *this = malloc_thing(private_delete_half_open_ike_sa_job_t);
|
||||
|
||||
/* interface functions */
|
||||
this->public.job_interface.get_type = (job_type_t (*) (job_t *)) get_type;
|
||||
/* same as destroy */
|
||||
this->public.job_interface.destroy_all = (void (*) (job_t *)) destroy;
|
||||
this->public.job_interface.destroy = (void (*)(job_t *)) destroy;;
|
||||
|
||||
/* public functions */
|
||||
this->public.get_ike_sa_id = (ike_sa_id_t * (*)(delete_half_open_ike_sa_job_t *)) get_ike_sa_id;
|
||||
this->public.destroy = (void (*)(delete_half_open_ike_sa_job_t *)) destroy;
|
||||
|
||||
/* private variables */
|
||||
this->ike_sa_id = ike_sa_id->clone(ike_sa_id);
|
||||
|
||||
return &(this->public);
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* @file delete_half_open_ike_sa_job.h
|
||||
*
|
||||
* @brief Interface of delete_half_open_ike_sa_job_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef DELETE_HALF_OPEN_IKE_SA_JOB_H_
|
||||
#define DELETE_HALF_OPEN_IKE_SA_JOB_H_
|
||||
|
||||
#include <types.h>
|
||||
#include <sa/ike_sa_id.h>
|
||||
#include <queues/jobs/job.h>
|
||||
|
||||
|
||||
typedef struct delete_half_open_ike_sa_job_t delete_half_open_ike_sa_job_t;
|
||||
|
||||
/**
|
||||
* @brief Class representing an DELETE_HALF_OPEN_IKE_SA Job.
|
||||
*
|
||||
* This job is responsible for deleting of half open IKE_SAs. A half
|
||||
* open IKE_SA is every IKE_SA which hasn't reache the ike_sa_established
|
||||
* state.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - delete_half_open_ike_sa_job_create()
|
||||
*
|
||||
* @ingroup jobs
|
||||
*/
|
||||
struct delete_half_open_ike_sa_job_t {
|
||||
/**
|
||||
* The job_t interface.
|
||||
*/
|
||||
job_t job_interface;
|
||||
|
||||
/**
|
||||
* @brief Returns the currently set ike_sa_id.
|
||||
*
|
||||
* @warning Returned object is not copied.
|
||||
*
|
||||
* @param this calling delete_half_open_ike_sa_job_t object
|
||||
* @return ike_sa_id_t object
|
||||
*/
|
||||
ike_sa_id_t * (*get_ike_sa_id) (delete_half_open_ike_sa_job_t *this);
|
||||
|
||||
/**
|
||||
* @brief Destroys an delete_half_open_ike_sa_job_t object (including assigned data).
|
||||
*
|
||||
* @param this delete_half_open_ike_sa_job_t object to destroy
|
||||
*/
|
||||
void (*destroy) (delete_half_open_ike_sa_job_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Creates a job of type DELETE_HALF_OPEN_IKE_SA.
|
||||
*
|
||||
* @param ike_sa_id id of the IKE_SA to delete
|
||||
* @return created delete_half_open_ike_sa_job_t object
|
||||
*
|
||||
* @ingroup jobs
|
||||
*/
|
||||
delete_half_open_ike_sa_job_t *delete_half_open_ike_sa_job_create(ike_sa_id_t *ike_sa_id);
|
||||
|
||||
#endif /*DELETE_HALF_OPEN_IKE_SA_JOB_H_*/
|
||||
@@ -0,0 +1,102 @@
|
||||
/**
|
||||
* @file incoming_packet_job.h
|
||||
*
|
||||
* @brief Implementation of incoming_packet_job_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
|
||||
#include "incoming_packet_job.h"
|
||||
|
||||
|
||||
|
||||
typedef struct private_incoming_packet_job_t private_incoming_packet_job_t;
|
||||
|
||||
/**
|
||||
* Private data of an incoming_packet_job_t Object
|
||||
*/
|
||||
struct private_incoming_packet_job_t {
|
||||
/**
|
||||
* public incoming_packet_job_t interface
|
||||
*/
|
||||
incoming_packet_job_t public;
|
||||
|
||||
/**
|
||||
* Assigned packet
|
||||
*/
|
||||
packet_t *packet;
|
||||
};
|
||||
|
||||
/**
|
||||
* Implements job_t.get_type.
|
||||
*/
|
||||
static job_type_t get_type(private_incoming_packet_job_t *this)
|
||||
{
|
||||
return INCOMING_PACKET;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements incoming_packet_job_t.get_packet.
|
||||
*/
|
||||
static packet_t *get_packet(private_incoming_packet_job_t *this)
|
||||
{
|
||||
return this->packet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements job_t.destroy_all.
|
||||
*/
|
||||
static void destroy_all(private_incoming_packet_job_t *this)
|
||||
{
|
||||
if (this->packet != NULL)
|
||||
{
|
||||
this->packet->destroy(this->packet);
|
||||
}
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements job_t.destroy.
|
||||
*/
|
||||
static void destroy(job_t *job)
|
||||
{
|
||||
private_incoming_packet_job_t *this = (private_incoming_packet_job_t *) job;
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
incoming_packet_job_t *incoming_packet_job_create(packet_t *packet)
|
||||
{
|
||||
private_incoming_packet_job_t *this = malloc_thing(private_incoming_packet_job_t);
|
||||
|
||||
/* interface functions */
|
||||
this->public.job_interface.get_type = (job_type_t (*) (job_t *)) get_type;
|
||||
this->public.job_interface.destroy_all = (void (*) (job_t *)) destroy_all;
|
||||
this->public.job_interface.destroy = destroy;
|
||||
|
||||
/* public functions */
|
||||
this->public.get_packet = (packet_t * (*)(incoming_packet_job_t *)) get_packet;
|
||||
this->public.destroy = (void (*)(incoming_packet_job_t *)) destroy;
|
||||
|
||||
/* private variables */
|
||||
this->packet = packet;
|
||||
|
||||
return &(this->public);
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* @file incoming_packet_job.h
|
||||
*
|
||||
* @brief Interface of incoming_packet_job_t.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Jan Hutter, Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef INCOMING_PACKET_JOB_H_
|
||||
#define INCOMING_PACKET_JOB_H_
|
||||
|
||||
#include <types.h>
|
||||
#include <network/packet.h>
|
||||
#include <queues/jobs/job.h>
|
||||
|
||||
|
||||
typedef struct incoming_packet_job_t incoming_packet_job_t;
|
||||
|
||||
/**
|
||||
* @brief Class representing an INCOMING_PACKET Job.
|
||||
*
|
||||
* An incoming pack job is created from the receiver, which has
|
||||
* read a packet to process from the socket.
|
||||
*
|
||||
* @b Constructors:
|
||||
* - incoming_packet_job_create()
|
||||
*
|
||||
* @ingroup jobs
|
||||
*/
|
||||
struct incoming_packet_job_t {
|
||||
/**
|
||||
* implements job_t interface
|
||||
*/
|
||||
job_t job_interface;
|
||||
|
||||
/**
|
||||
* @brief Returns the assigned packet_t object
|
||||
*
|
||||
* @warning Returned packet is not cloned and has to get destroyed by the caller.
|
||||
*
|
||||
* @param this calling incoming_packet_job_t object
|
||||
* @return assigned packet
|
||||
*/
|
||||
packet_t *(*get_packet) (incoming_packet_job_t *this);
|
||||
|
||||
/**
|
||||
* @brief Destroys an incoming_packet_job_t object.
|
||||
*
|
||||
* @param this incoming_packet_job_t object to destroy
|
||||
*/
|
||||
void (*destroy) (incoming_packet_job_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Creates a job of type INCOMING_PACKET
|
||||
*
|
||||
* @param[in] packet packet to assign with this job
|
||||
* @return created incoming_packet_job_t object
|
||||
*
|
||||
* @ingroup jobs
|
||||
*/
|
||||
incoming_packet_job_t *incoming_packet_job_create(packet_t *packet);
|
||||
|
||||
#endif /*INCOMING_PACKET_JOB_H_*/
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user