Merge branch 'ikev1-clean' into ikev1-master
Conflicts: configure.in man/ipsec.conf.5.in src/libcharon/daemon.c src/libcharon/plugins/eap_ttls/eap_ttls_peer.c src/libcharon/plugins/eap_radius/eap_radius_accounting.c src/libcharon/plugins/eap_radius/eap_radius_forward.c src/libcharon/plugins/farp/farp_listener.c src/libcharon/sa/ike_sa.c src/libcharon/sa/keymat.c src/libcharon/sa/task_manager.c src/libcharon/sa/trap_manager.c src/libstrongswan/plugins/x509/x509_cert.c src/libstrongswan/utils.h Applied lost changes of moved files keymat.c and task_manager.c. Updated listener_t.message hook signature in new plugins.
This commit is contained in:
commit
b1f2f05c92
|
@ -16,7 +16,7 @@ dnl ===========================
|
|||
dnl initialize & set some vars
|
||||
dnl ===========================
|
||||
|
||||
AC_INIT(strongSwan,4.6.3dr2)
|
||||
AC_INIT(strongSwan,5.0.0dr1)
|
||||
AM_INIT_AUTOMAKE(tar-ustar)
|
||||
AC_CONFIG_MACRO_DIR([m4/config])
|
||||
PKG_PROG_PKG_CONFIG
|
||||
|
@ -130,6 +130,8 @@ ARG_ENABL_SET([eap-ttls], [enable EAP TTLS authentication module.])
|
|||
ARG_ENABL_SET([eap-peap], [enable EAP PEAP authentication module.])
|
||||
ARG_ENABL_SET([eap-tnc], [enable EAP TNC trusted network connect module.])
|
||||
ARG_ENABL_SET([eap-radius], [enable RADIUS proxy authentication module.])
|
||||
ARG_ENABL_SET([xauth-generic], [enable generic XAuth backend.])
|
||||
ARG_ENABL_SET([xauth-eap], [enable XAuth backend using EAP methods to verify passwords.])
|
||||
ARG_ENABL_SET([tnc-ifmap], [enable TNC IF-MAP module.])
|
||||
ARG_ENABL_SET([tnc-pdp], [enable TNC policy decision point module.])
|
||||
ARG_ENABL_SET([tnc-imc], [enable TNC IMC module.])
|
||||
|
@ -160,11 +162,13 @@ ARG_ENABL_SET([manager], [enable web management console (proof of concept
|
|||
ARG_ENABL_SET([mediation], [enable IKEv2 Mediation Extension.])
|
||||
ARG_ENABL_SET([integrity-test], [enable integrity testing of libstrongswan and plugins.])
|
||||
ARG_DISBL_SET([load-warning], [disable the charon/pluto plugin load option warning in starter.])
|
||||
ARG_DISBL_SET([pluto], [disable the IKEv1 keying daemon pluto.])
|
||||
ARG_ENABL_SET([pluto], [enable the IKEv1 keying daemon pluto.])
|
||||
ARG_DISBL_SET([ikev1], [disable IKEv1 protocol support in charon.])
|
||||
ARG_DISBL_SET([ikev2], [disable IKEv2 protocol support in charon.])
|
||||
ARG_DISBL_SET([xauth], [disable xauth plugin.])
|
||||
ARG_DISBL_SET([threads], [disable the use of threads in pluto. Charon always uses threads.])
|
||||
ARG_DISBL_SET([adns], [disable the use of adns in pluto (disables opportunistic encryption).])
|
||||
ARG_DISBL_SET([charon], [disable the IKEv2 keying daemon charon.])
|
||||
ARG_DISBL_SET([charon], [disable the IKEv1/IKEv2 keying daemon charon.])
|
||||
ARG_DISBL_SET([tools], [disable additional utilities (openac, scepclient and pki).])
|
||||
ARG_DISBL_SET([scripts], [disable additional utilities (found in directory scripts).])
|
||||
ARG_ENABL_SET([conftest], [enforce Suite B conformance test framework.])
|
||||
|
@ -871,6 +875,8 @@ ADD_PLUGIN([eap-tls], [c libcharon])
|
|||
ADD_PLUGIN([eap-ttls], [c libcharon])
|
||||
ADD_PLUGIN([eap-peap], [c libcharon])
|
||||
ADD_PLUGIN([eap-tnc], [c libcharon])
|
||||
ADD_PLUGIN([xauth-generic], [c libcharon])
|
||||
ADD_PLUGIN([xauth-eap], [c libcharon])
|
||||
ADD_PLUGIN([tnc-ifmap], [c libcharon])
|
||||
ADD_PLUGIN([tnc-pdp], [c libcharon])
|
||||
ADD_PLUGIN([tnc-imc], [c libcharon])
|
||||
|
@ -995,6 +1001,8 @@ AM_CONDITIONAL(USE_EAP_TTLS, test x$eap_ttls = xtrue)
|
|||
AM_CONDITIONAL(USE_EAP_PEAP, test x$eap_peap = xtrue)
|
||||
AM_CONDITIONAL(USE_EAP_TNC, test x$eap_tnc = xtrue)
|
||||
AM_CONDITIONAL(USE_EAP_RADIUS, test x$eap_radius = xtrue)
|
||||
AM_CONDITIONAL(USE_XAUTH_GENERIC, test x$xauth_generic = xtrue)
|
||||
AM_CONDITIONAL(USE_XAUTH_EAP, test x$xauth_eap = xtrue)
|
||||
AM_CONDITIONAL(USE_TNC_IFMAP, test x$tnc_ifmap = xtrue)
|
||||
AM_CONDITIONAL(USE_TNC_PDP, test x$tnc_pdp = xtrue)
|
||||
AM_CONDITIONAL(USE_TNC_IMC, test x$tnc_imc = xtrue)
|
||||
|
@ -1045,6 +1053,8 @@ AM_CONDITIONAL(USE_ME, test x$mediation = xtrue)
|
|||
AM_CONDITIONAL(USE_INTEGRITY_TEST, test x$integrity_test = xtrue)
|
||||
AM_CONDITIONAL(USE_LOAD_WARNING, test x$load_warning = xtrue)
|
||||
AM_CONDITIONAL(USE_PLUTO, test x$pluto = xtrue)
|
||||
AM_CONDITIONAL(USE_IKEV1, test x$ikev1 = xtrue)
|
||||
AM_CONDITIONAL(USE_IKEV2, test x$ikev2 = xtrue)
|
||||
AM_CONDITIONAL(USE_THREADS, test x$threads = xtrue)
|
||||
AM_CONDITIONAL(USE_ADNS, test x$adns = xtrue)
|
||||
AM_CONDITIONAL(USE_CHARON, test x$charon = xtrue)
|
||||
|
@ -1080,7 +1090,12 @@ fi
|
|||
if test x$monolithic = xtrue; then
|
||||
AC_DEFINE(MONOLITHIC)
|
||||
fi
|
||||
|
||||
if test x$ikev1 = xtrue; then
|
||||
AC_DEFINE(USE_IKEV1)
|
||||
fi
|
||||
if test x$ikev2 = xtrue; then
|
||||
AC_DEFINE(USE_IKEV2)
|
||||
fi
|
||||
|
||||
dnl ==============================
|
||||
dnl build Makefiles
|
||||
|
@ -1174,6 +1189,8 @@ AC_OUTPUT(
|
|||
src/libcharon/plugins/eap_peap/Makefile
|
||||
src/libcharon/plugins/eap_tnc/Makefile
|
||||
src/libcharon/plugins/eap_radius/Makefile
|
||||
src/libcharon/plugins/xauth_generic/Makefile
|
||||
src/libcharon/plugins/xauth_eap/Makefile
|
||||
src/libcharon/plugins/tnc_ifmap/Makefile
|
||||
src/libcharon/plugins/tnc_pdp/Makefile
|
||||
src/libcharon/plugins/tnc_imc/Makefile
|
||||
|
|
|
@ -172,9 +172,9 @@ keying, rekeying, and general control.
|
|||
The path to control the connection is called 'ISAKMP SA' in IKEv1
|
||||
and 'IKE SA' in the IKEv2 protocol. That what is being negotiated, the kernel
|
||||
level data path, is called 'IPsec SA' or 'Child SA'.
|
||||
strongSwan currently uses two separate keying daemons. \fIpluto\fP handles
|
||||
all IKEv1 connections, \fIcharon\fP is the daemon handling the IKEv2
|
||||
protocol.
|
||||
strongSwan previously used two separate keying daemons, \fIpluto\fP and
|
||||
\fIcharon\fP. This manual does not discuss \fIpluto\fP options anymore, but
|
||||
only \fIcharon\fP that since strongSwan 5.0 supports both IKEv1 and IKEv2.
|
||||
.PP
|
||||
To avoid trivial editing of the configuration file to suit it to each system
|
||||
involved in a connection,
|
||||
|
@ -237,17 +237,7 @@ identity (such as EAP-TLS), but it does not match the IKEv2 gateway identity.
|
|||
includes conn section
|
||||
.BR <name> .
|
||||
.TP
|
||||
.BR auth " = " esp " | ah"
|
||||
whether authentication should be done as part of
|
||||
ESP encryption, or separately using the AH protocol;
|
||||
acceptable values are
|
||||
.B esp
|
||||
(the default) and
|
||||
.BR ah .
|
||||
.br
|
||||
The IKEv2 daemon currently supports ESP only.
|
||||
.TP
|
||||
.BR authby " = " pubkey " | rsasig | ecdsasig | psk | eap | never | xauth..."
|
||||
.BR authby " = " pubkey " | rsasig | ecdsasig | psk | never | xauthpsk | xauthrsasig"
|
||||
how the two security gateways should authenticate each other;
|
||||
acceptable values are
|
||||
.B psk
|
||||
|
@ -268,17 +258,12 @@ IKEv1 additionally supports the values
|
|||
.B xauthpsk
|
||||
and
|
||||
.B xauthrsasig
|
||||
that will enable eXtended Authentication (XAuth) in addition to IKEv1 main mode
|
||||
based on shared secrets or digital RSA signatures, respectively.
|
||||
IKEv2 additionally supports the value
|
||||
.BR eap ,
|
||||
which indicates an initiator to request EAP authentication. The EAP method
|
||||
to use is selected by the server (see
|
||||
.BR eap ).
|
||||
This parameter is deprecated for IKEv2 connections, as two peers do not need
|
||||
to agree on an authentication method. Use the
|
||||
that will enable eXtended AUTHentication (XAUTH) in addition to IKEv1 main mode
|
||||
based on shared secrets or digital RSA signatures, respectively.
|
||||
This parameter is deprecated, as two peers do not need to agree on an
|
||||
authentication method in IKEv2. Use the
|
||||
.B leftauth
|
||||
parameter instead to define authentication methods in IKEv2.
|
||||
parameter instead to define authentication methods.
|
||||
.TP
|
||||
.BR auto " = " ignore " | add | route | start"
|
||||
what operation, if any, should be done automatically at IPsec startup;
|
||||
|
@ -323,7 +308,8 @@ and prefer compressed.
|
|||
A value of
|
||||
.B no
|
||||
prevents IPsec from proposing compression;
|
||||
a proposal to compress will still be accepted.
|
||||
a proposal to compress will still be accepted. IPComp is currently not supported
|
||||
with IKEv1.
|
||||
.TP
|
||||
.BR dpdaction " = " none " | clear | hold | restart"
|
||||
controls the use of the Dead Peer Detection protocol (DPD, RFC 3706) where
|
||||
|
@ -341,16 +327,9 @@ put in the hold state
|
|||
.RB ( hold )
|
||||
or restarted
|
||||
.RB ( restart ).
|
||||
For IKEv1, the default is
|
||||
The default is
|
||||
.B none
|
||||
which disables the active sending of R_U_THERE notifications.
|
||||
Nevertheless pluto will always send the DPD Vendor ID during connection set up
|
||||
in order to signal the readiness to act passively as a responder if the peer
|
||||
wants to use DPD. For IKEv2,
|
||||
.B none
|
||||
does't make sense, since all messages are used to detect dead peers. If specified,
|
||||
it has the same meaning as the default
|
||||
.RB ( clear ).
|
||||
which disables the active sending of DPD messages.
|
||||
.TP
|
||||
.BR dpddelay " = " 30s " | <time>"
|
||||
defines the period time interval with which R_U_THERE messages/INFORMATIONAL
|
||||
|
@ -359,48 +338,16 @@ received. In IKEv2, a value of 0 sends no additional INFORMATIONAL
|
|||
messages and uses only standard messages (such as those to rekey) to detect
|
||||
dead peers.
|
||||
.TP
|
||||
.BR dpdtimeout " = " 150s " | <time>"
|
||||
defines the timeout interval, after which all connections to a peer are deleted
|
||||
in case of inactivity. This only applies to IKEv1, in IKEv2 the default
|
||||
retransmission timeout applies, as every exchange is used to detect dead peers.
|
||||
See
|
||||
.IR strongswan.conf (5)
|
||||
for a description of the IKEv2 retransmission timeout.
|
||||
.TP
|
||||
.BR closeaction " = " none " | clear | hold | restart"
|
||||
defines the action to take if the remote peer unexpectedly closes a CHILD_SA
|
||||
(IKEv2 only, see dpdaction for meaning of values). A closeaction should not be
|
||||
defines the action to take if the remote peer unexpectedly closes a CHILD_SA.
|
||||
A closeaction should not be
|
||||
used if the peer uses reauthentication or uniquids checking, as these events
|
||||
might trigger a closeaction when not desired.
|
||||
might trigger a closeaction when not desired. Closeactions are currently
|
||||
not supported with IKEv1.
|
||||
.TP
|
||||
.BR inactivity " = <time>"
|
||||
defines the timeout interval, after which a CHILD_SA is closed if it did
|
||||
not send or receive any traffic. Currently supported in IKEv2 connections only.
|
||||
.TP
|
||||
.BR eap " = md5 | mschapv2 | radius | ... | <type> | <type>-<vendor>
|
||||
defines the EAP type to propose as server if the client requests EAP
|
||||
authentication. Currently supported values are
|
||||
.B aka
|
||||
for EAP-AKA,
|
||||
.B gtc
|
||||
for EAP-GTC,
|
||||
.B md5
|
||||
for EAP-MD5,
|
||||
.B mschapv2
|
||||
for EAP-MS-CHAPv2,
|
||||
.B radius
|
||||
for the EAP-RADIUS proxy and
|
||||
.B sim
|
||||
for EAP-SIM. Additionally, IANA assigned EAP method numbers are accepted, or a
|
||||
definition in the form
|
||||
.B eap=type-vendor
|
||||
(e.g. eap=7-12345) can be used to specify vendor specific EAP types.
|
||||
This parameter is deprecated in the favour of
|
||||
.B leftauth.
|
||||
|
||||
To forward EAP authentication to a RADIUS server using the EAP-RADIUS plugin,
|
||||
set
|
||||
.BR eap=radius .
|
||||
not send or receive any traffic.
|
||||
.TP
|
||||
.BR eap_identity " = <id>"
|
||||
defines the identity the client uses to reply to a EAP Identity request.
|
||||
|
@ -418,15 +365,15 @@ The notation is
|
|||
.BR encryption-integrity[-dhgroup][-esnmode] .
|
||||
.br
|
||||
Defaults to
|
||||
.BR aes128-sha1,3des-sha1
|
||||
for IKEv1. The IKEv2 daemon adds its extensive default proposal to this default
|
||||
.BR aes128-sha1,3des-sha1 .
|
||||
The daemon adds its extensive default proposal to this default
|
||||
or the configured value. To restrict it to the configured proposal an
|
||||
exclamation mark
|
||||
.RB ( ! )
|
||||
can be added at the end.
|
||||
.br
|
||||
.BR Note :
|
||||
As a responder both daemons accept the first supported proposal received from
|
||||
As a responder the daemon accepts the first supported proposal received from
|
||||
the peer. In order to restrict a responder to only accept specific cipher
|
||||
suites, the strict flag
|
||||
.RB ( ! ,
|
||||
|
@ -434,8 +381,8 @@ exclamation mark) can be used, e.g: aes256-sha512-modp4096!
|
|||
.br
|
||||
If
|
||||
.B dh-group
|
||||
is specified, CHILD_SA setup and rekeying include a separate Diffie-Hellman
|
||||
exchange (IKEv2 only). Valid values for
|
||||
is specified, CHILD_SA/Quick Mode setup and rekeying include a separate
|
||||
Diffie-Hellman exchange. Valid values for
|
||||
.B esnmode
|
||||
(IKEv2 only) are
|
||||
.B esn
|
||||
|
@ -448,7 +395,7 @@ the default is
|
|||
.BR forceencaps " = yes | " no
|
||||
force UDP encapsulation for ESP packets even if no NAT situation is detected.
|
||||
This may help to surmount restrictive firewalls. In order to force the peer to
|
||||
encapsulate packets, NAT detection payloads are faked (IKEv2 only).
|
||||
encapsulate packets, NAT detection payloads are faked.
|
||||
.TP
|
||||
.BR ike " = <cipher suites>"
|
||||
comma-separated list of IKE/ISAKMP SA encryption/authentication algorithms
|
||||
|
@ -460,15 +407,15 @@ In IKEv2, multiple algorithms and proposals may be included, such as
|
|||
aes128-aes256-sha1-modp1536-modp2048,3des-sha1-md5-modp1024.
|
||||
.br
|
||||
Defaults to
|
||||
.B aes128-sha1-modp2048,3des-sha1-modp1536
|
||||
for IKEv1. The IKEv2 daemon adds its extensive default proposal to this
|
||||
.B aes128-sha1-modp2048,3des-sha1-modp1536 .
|
||||
The daemon adds its extensive default proposal to this
|
||||
default or the configured value. To restrict it to the configured proposal an
|
||||
exclamation mark
|
||||
.RB ( ! )
|
||||
can be added at the end.
|
||||
.br
|
||||
.BR Note :
|
||||
As a responder both daemons accept the first supported proposal received from
|
||||
As a responder the daemon accepts the first supported proposal received from
|
||||
the peer. In order to restrict a responder to only accept specific cipher
|
||||
suites, the strict flag
|
||||
.BR ( ! ,
|
||||
|
@ -479,8 +426,8 @@ how long the keying channel of a connection (ISAKMP or IKE SA)
|
|||
should last before being renegotiated. Also see EXPIRY/REKEY below.
|
||||
.TP
|
||||
.BR installpolicy " = " yes " | no"
|
||||
decides whether IPsec policies are installed in the kernel by the IKEv2
|
||||
charon daemon for a given connection. Allows peaceful cooperation e.g. with
|
||||
decides whether IPsec policies are installed in the kernel by the charon daemon
|
||||
for a given connection. Allows peaceful cooperation e.g. with
|
||||
the Mobile IPv6 daemon mip6d who wants to control the kernel policies.
|
||||
Acceptable values are
|
||||
.B yes
|
||||
|
@ -490,19 +437,8 @@ Acceptable values are
|
|||
.BR keyexchange " = " ike " | ikev1 | ikev2"
|
||||
method of key exchange;
|
||||
which protocol should be used to initialize the connection. Connections marked with
|
||||
.B ikev1
|
||||
are initiated with pluto, those marked with
|
||||
.B ikev2
|
||||
with charon. An incoming request from the remote peer is handled by the correct
|
||||
daemon, unaffected from the
|
||||
.B keyexchange
|
||||
setting. Starting with strongSwan 4.5 the default value
|
||||
.B ike
|
||||
is a synonym for
|
||||
.BR ikev2 ,
|
||||
whereas in older strongSwan releases
|
||||
.B ikev1
|
||||
was assumed.
|
||||
use IKEv2 when initiating, but accept any protocol version when responding.
|
||||
.TP
|
||||
.BR keyingtries " = " 3 " | <number> | %forever"
|
||||
how many attempts (a whole number or \fB%forever\fP) should be made to
|
||||
|
@ -534,18 +470,8 @@ or
|
|||
may be
|
||||
.BR %defaultroute ,
|
||||
but not both.
|
||||
The prefix
|
||||
.B %
|
||||
in front of a fully-qualified domain name or an IP address will implicitly set
|
||||
.B leftallowany=yes.
|
||||
If the domain name cannot be resolved into an IP address at IPsec startup or
|
||||
update time then
|
||||
.B left=%any
|
||||
and
|
||||
.B leftallowany=no
|
||||
will be assumed.
|
||||
|
||||
In case of an IKEv2 connection, the value
|
||||
The value
|
||||
.B %any
|
||||
for the local endpoint signifies an address to be filled in (by automatic
|
||||
keying) during negotiation. If the local peer initiates the connection setup
|
||||
|
@ -553,9 +479,6 @@ the routing table will be queried to determine the correct local IP address.
|
|||
In case the local peer is responding to a connection setup then any IP address
|
||||
that is assigned to a local interface will be accepted.
|
||||
.br
|
||||
Note that specifying
|
||||
.B %any
|
||||
for the local endpoint is not supported by the IKEv1 pluto daemon.
|
||||
|
||||
If
|
||||
.B %any
|
||||
|
@ -565,30 +488,18 @@ Please note that with the usage of wildcards multiple connection descriptions
|
|||
might match a given incoming connection attempt. The most specific description
|
||||
is used in that case.
|
||||
.TP
|
||||
.BR leftallowany " = yes | " no
|
||||
a modifier for
|
||||
.B left
|
||||
, making it behave as
|
||||
.B %any
|
||||
although a concrete IP address has been assigned.
|
||||
Recommended for dynamic IP addresses that can be resolved by DynDNS at IPsec
|
||||
startup or update time.
|
||||
Acceptable values are
|
||||
.B yes
|
||||
and
|
||||
.B no
|
||||
(the default).
|
||||
.TP
|
||||
.BR leftauth " = <auth method>"
|
||||
Authentication method to use locally (left) or require from the remote (right)
|
||||
side.
|
||||
This parameter is supported in IKEv2 only. Acceptable values are
|
||||
Acceptable values are
|
||||
.B pubkey
|
||||
for public key authentication (RSA/ECDSA),
|
||||
.B psk
|
||||
for pre-shared key authentication and
|
||||
for pre-shared key authentication,
|
||||
.B eap
|
||||
to (require the) use of the Extensible Authentication Protocol.
|
||||
to (require the) use of the Extensible Authentication Protocol in IKEv2, and
|
||||
.B xauth
|
||||
for IKEv1 eXtended Authentication.
|
||||
To require a trustchain public key strength for the remote side, specify the
|
||||
key type followed by the strength in bits (for example
|
||||
.BR rsa-2048
|
||||
|
@ -598,24 +509,37 @@ For
|
|||
.B eap,
|
||||
an optional EAP method can be appended. Currently defined methods are
|
||||
.BR eap-aka ,
|
||||
.BR eap-sim ,
|
||||
.BR eap-gtc ,
|
||||
.BR eap-md5 ,
|
||||
.BR eap-tls ,
|
||||
.B eap-mschapv2
|
||||
and
|
||||
.BR eap-sim .
|
||||
.BR eap-radius .
|
||||
Alternatively, IANA assigned EAP method numbers are accepted. Vendor specific
|
||||
EAP methods are defined in the form
|
||||
.B eap-type-vendor
|
||||
.RB "(e.g. " eap-7-12345 ).
|
||||
For
|
||||
.B xauth,
|
||||
a XAuth authentication backend can be specified, such as
|
||||
.B xauth-generic
|
||||
or
|
||||
.B xauth-eap .
|
||||
If XAuth is used in
|
||||
.BR leftauth ,
|
||||
Hybrid authentication is used. For traditional XAuth authentication, define
|
||||
XAuth in
|
||||
.BR lefauth2 .
|
||||
.TP
|
||||
.BR leftauth2 " = <auth method>"
|
||||
Same as
|
||||
.BR leftauth ,
|
||||
but defines an additional authentication exchange. IKEv2 supports multiple
|
||||
but defines an additional authentication exchange. In IKEv1, only XAuth can be
|
||||
used in the second authentication round. IKEv2 supports multiple complete
|
||||
authentication rounds using "Multiple Authentication Exchanges" defined
|
||||
in RFC4739. This allows, for example, separated authentication
|
||||
of host and user (IKEv2 only).
|
||||
of host and user.
|
||||
.TP
|
||||
.BR leftca " = <issuer dn> | %same"
|
||||
the distinguished name of a certificate authority which is required to
|
||||
|
@ -674,8 +598,7 @@ tunnels established with IPsec are exempted from it
|
|||
so that packets can flow unchanged through the tunnels.
|
||||
(This means that all subnets connected in this manner must have
|
||||
distinct, non-overlapping subnet address blocks.)
|
||||
This is done by the default \fBipsec _updown\fR script (see
|
||||
.IR pluto (8)).
|
||||
This is done by the default \fBipsec _updown\fR script.
|
||||
|
||||
In situations calling for more control,
|
||||
it may be preferable for the user to supply his own
|
||||
|
@ -687,12 +610,7 @@ which makes the appropriate adjustments for his system.
|
|||
a comma separated list of group names. If the
|
||||
.B leftgroups
|
||||
parameter is present then the peer must be a member of at least one
|
||||
of the groups defined by the parameter. Group membership must be certified
|
||||
by a valid attribute certificate stored in \fI/etc/ipsec.d/acerts/\fP thas has
|
||||
been issued to the peer by a trusted Authorization Authority stored in
|
||||
\fI/etc/ipsec.d/aacerts/\fP.
|
||||
.br
|
||||
Attribute certificates are not supported in IKEv2 yet.
|
||||
of the groups defined by the parameter.
|
||||
.TP
|
||||
.BR lefthostaccess " = yes | " no
|
||||
inserts a pair of INPUT and OUTPUT iptables rules using the default
|
||||
|
@ -719,8 +637,8 @@ identity to use for a second authentication for the left participant
|
|||
.BR leftid .
|
||||
.TP
|
||||
.BR leftikeport " = <port>"
|
||||
UDP port the left participant uses for IKE communication. Currently supported in
|
||||
IKEv2 connections only. If unspecified, port 500 is used with the port floating
|
||||
UDP port the left participant uses for IKE communication.
|
||||
If unspecified, port 500 is used with the port floating
|
||||
to 4500 if a NAT is detected or MOBIKE is enabled. Specifying a local IKE port
|
||||
different from the default additionally requires a socket implementation that
|
||||
listens to this port.
|
||||
|
@ -742,29 +660,6 @@ or
|
|||
or
|
||||
.B leftprotoport=udp
|
||||
.TP
|
||||
.BR leftrsasigkey " = " %cert " | <raw rsa public key>"
|
||||
the left participant's
|
||||
public key for RSA signature authentication,
|
||||
in RFC 2537 format using
|
||||
.IR ttodata (3)
|
||||
encoding.
|
||||
The magic value
|
||||
.B %none
|
||||
means the same as not specifying a value (useful to override a default).
|
||||
The value
|
||||
.B %cert
|
||||
(the default)
|
||||
means that the key is extracted from a certificate.
|
||||
The identity used for the left participant
|
||||
must be a specific host, not
|
||||
.B %any
|
||||
or another magic value.
|
||||
.B Caution:
|
||||
if two connection descriptions
|
||||
specify different public keys for the same
|
||||
.BR leftid ,
|
||||
confusion and madness will ensue.
|
||||
.TP
|
||||
.BR leftsendcert " = never | no | " ifasked " | always | yes"
|
||||
Accepted values are
|
||||
.B never
|
||||
|
@ -786,8 +681,7 @@ value is one of the synonyms
|
|||
.BR %modeconfig ,
|
||||
or
|
||||
.BR %modecfg ,
|
||||
an address is requested from the peer. In IKEv2, a statically defined address
|
||||
is also requested, since the server may change it.
|
||||
an address is requested from the peer.
|
||||
.TP
|
||||
.BR rightsourceip " = %config | <network>/<netmask> | %poolname"
|
||||
The internal source IP to use in a tunnel for the remote peer. If the
|
||||
|
@ -804,16 +698,11 @@ private subnet behind the left participant, expressed as
|
|||
\fInetwork\fB/\fInetmask\fR;
|
||||
if omitted, essentially assumed to be \fIleft\fB/32\fR,
|
||||
signifying that the left end of the connection goes to the left participant
|
||||
only. When using IKEv2, the configured subnet of the peers may differ, the
|
||||
protocol narrows it to the greatest common subnet. Further, IKEv2 supports
|
||||
multiple subnets separated by commas. IKEv1 only interprets the first subnet
|
||||
of such a definition.
|
||||
.TP
|
||||
.BR leftsubnetwithin " = <ip subnet>"
|
||||
the peer can propose any subnet or single IP address that fits within the
|
||||
range defined by
|
||||
.BR leftsubnetwithin.
|
||||
Not relevant for IKEv2, as subnets are narrowed.
|
||||
only. Configured subnet of the peers may differ, the protocol narrows it to
|
||||
the greatest common subnet. In IKEv1, this may lead to problems with other
|
||||
implementations, make sure to configure identical subnets in such
|
||||
configurations. IKEv2 supports multiple subnets separated by commas, IKEv1 only
|
||||
interprets the first subnet of such a definition.
|
||||
.TP
|
||||
.BR leftupdown " = <path>"
|
||||
what ``updown'' script to run to adjust routing and/or firewalling
|
||||
|
@ -823,20 +712,15 @@ changes (default
|
|||
May include positional parameters separated by white space
|
||||
(although this requires enclosing the whole string in quotes);
|
||||
including shell metacharacters is unwise.
|
||||
See
|
||||
.IR pluto (8)
|
||||
for details.
|
||||
Relevant only locally, other end need not agree on it. IKEv2 uses the updown
|
||||
Relevant only locally, other end need not agree on it. Charon uses the updown
|
||||
script to insert firewall rules only, since routing has been implemented
|
||||
directly into charon.
|
||||
directly into the daemon.
|
||||
.TP
|
||||
.BR lifebytes " = <number>"
|
||||
the number of bytes transmitted over an IPsec SA before it expires (IKEv2
|
||||
only).
|
||||
the number of bytes transmitted over an IPsec SA before it expires.
|
||||
.TP
|
||||
.BR lifepackets " = <number>"
|
||||
the number of packets transmitted over an IPsec SA before it expires (IKEv2
|
||||
only).
|
||||
the number of packets transmitted over an IPsec SA before it expires.
|
||||
.TP
|
||||
.BR lifetime " = " 1h " | <time>"
|
||||
how long a particular instance of a connection
|
||||
|
@ -868,12 +752,12 @@ which thinks the lifetime is longer. Also see EXPIRY/REKEY below.
|
|||
.BR marginbytes " = <number>"
|
||||
how many bytes before IPsec SA expiry (see
|
||||
.BR lifebytes )
|
||||
should attempts to negotiate a replacement begin (IKEv2 only).
|
||||
should attempts to negotiate a replacement begin.
|
||||
.TP
|
||||
.BR marginpackets " = <number>"
|
||||
how many packets before IPsec SA expiry (see
|
||||
.BR lifepackets )
|
||||
should attempts to negotiate a replacement begin (IKEv2 only).
|
||||
should attempts to negotiate a replacement begin.
|
||||
.TP
|
||||
.BR margintime " = " 9m " | <time>"
|
||||
how long before connection expiry or keying-channel expiry
|
||||
|
@ -912,7 +796,7 @@ enables the IKEv2 MOBIKE protocol defined by RFC 4555. Accepted values are
|
|||
.BR no .
|
||||
If set to
|
||||
.BR no ,
|
||||
the IKEv2 charon daemon will not actively propose MOBIKE as initiator and
|
||||
the charon daemon will not actively propose MOBIKE as initiator and
|
||||
ignore the MOBIKE_SUPPORTED notify as responder.
|
||||
.TP
|
||||
.BR modeconfig " = push | " pull
|
||||
|
@ -922,29 +806,8 @@ Accepted values are
|
|||
and
|
||||
.B pull
|
||||
(the default).
|
||||
Currently relevant for IKEv1 only since IKEv2 always uses the configuration
|
||||
payload in pull mode. Cisco VPN gateways usually operate in
|
||||
.B push
|
||||
mode.
|
||||
.TP
|
||||
.BR pfs " = " yes " | no"
|
||||
whether Perfect Forward Secrecy of keys is desired on the connection's
|
||||
keying channel
|
||||
(with PFS, penetration of the key-exchange protocol
|
||||
does not compromise keys negotiated earlier);
|
||||
acceptable values are
|
||||
.B yes
|
||||
(the default)
|
||||
and
|
||||
.BR no.
|
||||
IKEv2 always uses PFS for IKE_SA rekeying whereas for CHILD_SA rekeying
|
||||
PFS is enforced by defining a Diffie-Hellman modp group in the
|
||||
.B esp
|
||||
parameter.
|
||||
.TP
|
||||
.BR pfsgroup " = <modp group>"
|
||||
defines a Diffie-Hellman group for perfect forward secrecy in IKEv1 Quick Mode
|
||||
differing from the DH group used for IKEv1 Main Mode (IKEv1 only).
|
||||
Push mode is currently not supported in charon, hence this parameter has no
|
||||
effect.
|
||||
.TP
|
||||
.BR reauth " = " yes " | no"
|
||||
whether rekeying of an IKE_SA should also reauthenticate the peer. In IKEv1,
|
||||
|
@ -964,7 +827,7 @@ and
|
|||
.BR no .
|
||||
The two ends need not agree, but while a value of
|
||||
.B no
|
||||
prevents pluto/charon from requesting renegotiation,
|
||||
prevents charon from requesting renegotiation,
|
||||
it does not prevent responding to renegotiation requested from the other end,
|
||||
so
|
||||
.B no
|
||||
|
@ -1026,11 +889,7 @@ signifying the special Mobile IPv6 transport proxy mode;
|
|||
.BR passthrough ,
|
||||
signifying that no IPsec processing should be done at all;
|
||||
.BR drop ,
|
||||
signifying that packets should be discarded; and
|
||||
.BR reject ,
|
||||
signifying that packets should be discarded and a diagnostic ICMP returned
|
||||
.RB ( reject
|
||||
is currently not supported by the NETKEY stack of the Linux 2.6 kernel).
|
||||
signifying that packets should be discarded.
|
||||
.TP
|
||||
.BR xauth " = " client " | server"
|
||||
specifies the role in the XAuth protocol if activated by
|
||||
|
@ -1107,8 +966,6 @@ synonym for
|
|||
.BR crluri2 " = <uri>"
|
||||
defines an alternative CRL distribution point (ldap, http, or file URI)
|
||||
.TP
|
||||
.BR ldaphost " = <hostname>"
|
||||
defines an ldap host. Currently used by IKEv1 only.
|
||||
.TP
|
||||
.BR ocspuri " = <uri>"
|
||||
defines an OCSP URI.
|
||||
|
@ -1118,7 +975,7 @@ synonym for
|
|||
.B ocspuri.
|
||||
.TP
|
||||
.BR ocspuri2 " = <uri>"
|
||||
defines an alternative OCSP URI. Currently used by IKEv2 only.
|
||||
defines an alternative OCSP URI.
|
||||
.TP
|
||||
.BR certuribase " = <uri>"
|
||||
defines the base URI for the Hash and URL feature supported by IKEv2.
|
||||
|
@ -1131,48 +988,12 @@ At present, the only
|
|||
section known to the IPsec software is the one named
|
||||
.BR setup ,
|
||||
which contains information used when the software is being started.
|
||||
Here's an example:
|
||||
.PP
|
||||
.ne 8
|
||||
.nf
|
||||
.ft B
|
||||
.ta 1c
|
||||
config setup
|
||||
plutodebug=all
|
||||
crlcheckinterval=10m
|
||||
strictcrlpolicy=yes
|
||||
.ft
|
||||
.fi
|
||||
.PP
|
||||
Parameters are optional unless marked ``(required)''.
|
||||
The currently-accepted
|
||||
.I parameter
|
||||
names in a
|
||||
.B config
|
||||
.B setup
|
||||
section affecting both daemons are:
|
||||
.TP
|
||||
.BR cachecrls " = yes | " no
|
||||
certificate revocation lists (CRLs) fetched via http or ldap will be cached in
|
||||
\fI/etc/ipsec.d/crls/\fR under a unique file name derived from the certification
|
||||
authority's public key.
|
||||
Accepted values are
|
||||
.B yes
|
||||
and
|
||||
.B no
|
||||
(the default). Only relevant for IKEv1, as CRLs are always cached in IKEv2.
|
||||
.TP
|
||||
.BR charonstart " = " yes " | no"
|
||||
whether to start the IKEv2 charon daemon or not.
|
||||
The default is
|
||||
.B yes
|
||||
if starter was compiled with IKEv2 support.
|
||||
.TP
|
||||
.BR plutostart " = " yes " | no"
|
||||
whether to start the IKEv1 pluto daemon or not.
|
||||
The default is
|
||||
.B yes
|
||||
if starter was compiled with IKEv1 support.
|
||||
section are:
|
||||
.TP
|
||||
.BR strictcrlpolicy " = yes | ifuri | " no
|
||||
defines if a fresh CRL must be available in order for the peer authentication
|
||||
|
@ -1198,116 +1019,13 @@ and
|
|||
Participant IDs normally \fIare\fR unique,
|
||||
so a new (automatically-keyed) connection using the same ID is
|
||||
almost invariably intended to replace an old one.
|
||||
The IKEv2 daemon also accepts the value
|
||||
The daemon also accepts the value
|
||||
.B replace
|
||||
which is identical to
|
||||
.B yes
|
||||
and the value
|
||||
.B keep
|
||||
to reject new IKE_SA setups and keep the duplicate established earlier.
|
||||
.PP
|
||||
The following
|
||||
.B config section
|
||||
parameters are used by the IKEv1 Pluto daemon only:
|
||||
.TP
|
||||
.BR crlcheckinterval " = " 0s " | <time>"
|
||||
interval in seconds. CRL fetching is enabled if the value is greater than zero.
|
||||
Asynchronous, periodic checking for fresh CRLs is currently done by the
|
||||
IKEv1 Pluto daemon only.
|
||||
.TP
|
||||
.BR keep_alive " = " 20s " | <time>"
|
||||
interval in seconds between NAT keep alive packets, the default being 20 seconds.
|
||||
.TP
|
||||
.BR nat_traversal " = yes | " no
|
||||
activates NAT traversal by accepting source ISAKMP ports different from udp/500 and
|
||||
being able of floating to udp/4500 if a NAT situation is detected.
|
||||
Accepted values are
|
||||
.B yes
|
||||
and
|
||||
.B no
|
||||
(the default).
|
||||
Used by IKEv1 only, NAT traversal is always being active in IKEv2.
|
||||
.TP
|
||||
.BR nocrsend " = yes | " no
|
||||
no certificate request payloads will be sent.
|
||||
.TP
|
||||
.BR pkcs11initargs " = <args>"
|
||||
non-standard argument string for PKCS#11 C_Initialize() function;
|
||||
required by NSS softoken.
|
||||
.TP
|
||||
.BR pkcs11module " = <args>"
|
||||
defines the path to a dynamically loadable PKCS #11 library.
|
||||
.TP
|
||||
.BR pkcs11keepstate " = yes | " no
|
||||
PKCS #11 login sessions will be kept during the whole lifetime of the keying
|
||||
daemon. Useful with pin-pad smart card readers.
|
||||
Accepted values are
|
||||
.B yes
|
||||
and
|
||||
.B no
|
||||
(the default).
|
||||
.TP
|
||||
.BR pkcs11proxy " = yes | " no
|
||||
Pluto will act as a PKCS #11 proxy accessible via the whack interface.
|
||||
Accepted values are
|
||||
.B yes
|
||||
and
|
||||
.B no
|
||||
(the default).
|
||||
.TP
|
||||
.BR plutodebug " = " none " | <debug list> | all"
|
||||
how much pluto debugging output should be logged.
|
||||
An empty value,
|
||||
or the magic value
|
||||
.BR none ,
|
||||
means no debugging output (the default).
|
||||
The magic value
|
||||
.B all
|
||||
means full output.
|
||||
Otherwise only the specified types of output
|
||||
(a quoted list, names without the
|
||||
.B \-\-debug\-
|
||||
prefix,
|
||||
separated by white space) are enabled;
|
||||
for details on available debugging types, see
|
||||
.IR pluto (8).
|
||||
.TP
|
||||
.BR plutostderrlog " = <file>"
|
||||
Pluto will not use syslog, but rather log to stderr, and redirect stderr
|
||||
to <file>.
|
||||
.TP
|
||||
.BR postpluto " = <command>"
|
||||
shell command to run after starting pluto
|
||||
(e.g., to remove a decrypted copy of the
|
||||
.I ipsec.secrets
|
||||
file).
|
||||
It's run in a very simple way;
|
||||
complexities like I/O redirection are best hidden within a script.
|
||||
Any output is redirected for logging,
|
||||
so running interactive commands is difficult unless they use
|
||||
.I /dev/tty
|
||||
or equivalent for their interaction.
|
||||
Default is none.
|
||||
.TP
|
||||
.BR prepluto " = <command>"
|
||||
shell command to run before starting pluto
|
||||
(e.g., to decrypt an encrypted copy of the
|
||||
.I ipsec.secrets
|
||||
file).
|
||||
It's run in a very simple way;
|
||||
complexities like I/O redirection are best hidden within a script.
|
||||
Any output is redirected for logging,
|
||||
so running interactive commands is difficult unless they use
|
||||
.I /dev/tty
|
||||
or equivalent for their interaction.
|
||||
Default is none.
|
||||
.TP
|
||||
.BR virtual_private " = <networks>"
|
||||
defines private networks using a wildcard notation.
|
||||
.PP
|
||||
The following
|
||||
.B config section
|
||||
parameters are used by the IKEv2 charon daemon only:
|
||||
.TP
|
||||
.BR charondebug " = <debug list>"
|
||||
how much charon debugging output should be logged.
|
||||
|
@ -1324,7 +1042,7 @@ is set to
|
|||
for all types. For more flexibility see LOGGER CONFIGURATION in
|
||||
.IR strongswan.conf (5).
|
||||
|
||||
.SH IKEv2 EXPIRY/REKEY
|
||||
.SH SA EXPIRY/REKEY
|
||||
The IKE SAs and IPsec SAs negotiated by the daemon can be configured to expire
|
||||
after a specific amount of time. For IPsec SAs this can also happen after a
|
||||
specified number of transmitted packets or transmitted bytes. The following
|
||||
|
@ -1410,7 +1128,7 @@ time equals zero and, thus, rekeying gets disabled.
|
|||
/etc/ipsec.d/crls
|
||||
|
||||
.SH SEE ALSO
|
||||
strongswan.conf(5), ipsec.secrets(5), ipsec(8), pluto(8)
|
||||
strongswan.conf(5), ipsec.secrets(5), ipsec(8)
|
||||
.SH HISTORY
|
||||
Originally written for the FreeS/WAN project by Henry Spencer.
|
||||
Updated and extended for the strongSwan project <http://www.strongswan.org> by
|
||||
|
|
|
@ -251,8 +251,8 @@ static peer_cfg_t *load_peer_config(private_config_t *this,
|
|||
uintptr_t strength;
|
||||
|
||||
ike_cfg = load_ike_config(this, settings, config);
|
||||
peer_cfg = peer_cfg_create(config, 2, ike_cfg, CERT_ALWAYS_SEND,
|
||||
UNIQUE_NO, 1, 0, 0, 0, 0, FALSE, 0,
|
||||
peer_cfg = peer_cfg_create(config, IKEV2, ike_cfg, CERT_ALWAYS_SEND,
|
||||
UNIQUE_NO, 1, 0, 0, 0, 0, FALSE, FALSE, 0,
|
||||
NULL, NULL, FALSE, NULL, NULL);
|
||||
|
||||
auth = auth_cfg_create();
|
||||
|
|
|
@ -60,9 +60,9 @@ struct private_add_notify_t {
|
|||
|
||||
METHOD(listener_t, message, bool,
|
||||
private_add_notify_t *this, ike_sa_t *ike_sa, message_t *message,
|
||||
bool incoming)
|
||||
bool incoming, bool plain)
|
||||
{
|
||||
if (!incoming &&
|
||||
if (!incoming && plain &&
|
||||
message->get_request(message) == this->req &&
|
||||
message->get_message_id(message) == this->id)
|
||||
{
|
||||
|
@ -89,7 +89,7 @@ METHOD(listener_t, message, bool,
|
|||
{
|
||||
data = chunk_clone(chunk_create(this->data, strlen(this->data)));
|
||||
}
|
||||
notify = notify_payload_create_from_protocol_and_type(
|
||||
notify = notify_payload_create_from_protocol_and_type(NOTIFY,
|
||||
this->esp ? PROTO_ESP : PROTO_IKE, type);
|
||||
notify->set_spi(notify, this->spi);
|
||||
if (data.len)
|
||||
|
|
|
@ -62,9 +62,9 @@ struct private_add_payload_t {
|
|||
|
||||
METHOD(listener_t, message, bool,
|
||||
private_add_payload_t *this, ike_sa_t *ike_sa, message_t *message,
|
||||
bool incoming)
|
||||
bool incoming, bool plain)
|
||||
{
|
||||
if (!incoming &&
|
||||
if (!incoming && plain &&
|
||||
message->get_request(message) == this->req &&
|
||||
message->get_message_id(message) == this->id)
|
||||
{
|
||||
|
|
|
@ -111,9 +111,9 @@ static linked_list_t* load_proposals(private_custom_proposal_t *this,
|
|||
|
||||
METHOD(listener_t, message, bool,
|
||||
private_custom_proposal_t *this, ike_sa_t *ike_sa, message_t *message,
|
||||
bool incoming)
|
||||
bool incoming, bool plain)
|
||||
{
|
||||
if (!incoming &&
|
||||
if (!incoming && plain &&
|
||||
message->get_request(message) == this->req &&
|
||||
message->get_message_id(message) == this->id)
|
||||
{
|
||||
|
@ -145,7 +145,7 @@ METHOD(listener_t, message, bool,
|
|||
proposal->get_protocol(proposal),
|
||||
proposal->get_spi(proposal));
|
||||
DBG1(DBG_CFG, "injecting custom proposal: %#P", new_props);
|
||||
new = sa_payload_create_from_proposal_list(new_props);
|
||||
new = sa_payload_create_from_proposals_v2(new_props);
|
||||
message->add_payload(message, (payload_t*)new);
|
||||
new_props->destroy_offset(new_props, offsetof(proposal_t, destroy));
|
||||
}
|
||||
|
|
|
@ -32,9 +32,9 @@ struct private_force_cookie_t {
|
|||
|
||||
METHOD(listener_t, message, bool,
|
||||
private_force_cookie_t *this, ike_sa_t *ike_sa, message_t *message,
|
||||
bool incoming)
|
||||
bool incoming, bool plain)
|
||||
{
|
||||
if (incoming && message->get_request(message) &&
|
||||
if (incoming && plain && message->get_request(message) &&
|
||||
message->get_exchange_type(message) == IKE_SA_INIT)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
|
@ -68,7 +68,7 @@ METHOD(listener_t, message, bool,
|
|||
chunk_t data = chunk_from_thing("COOKIE test data");
|
||||
|
||||
DBG1(DBG_CFG, "sending COOKIE: %#B", &data);
|
||||
response = message_create();
|
||||
response = message_create(IKEV2_MAJOR_VERSION, IKEV2_MINOR_VERSION);
|
||||
dst = message->get_source(message);
|
||||
src = message->get_destination(message);
|
||||
response->set_source(response, src->clone(src));
|
||||
|
|
|
@ -45,9 +45,9 @@ struct private_ignore_message_t {
|
|||
|
||||
METHOD(listener_t, message, bool,
|
||||
private_ignore_message_t *this, ike_sa_t *ike_sa, message_t *message,
|
||||
bool incoming)
|
||||
bool incoming, bool plain)
|
||||
{
|
||||
if (incoming == this->in &&
|
||||
if (incoming == this->in && plain &&
|
||||
message->get_request(message) == this->req &&
|
||||
message->get_message_id(message) == this->id)
|
||||
{
|
||||
|
|
|
@ -51,7 +51,10 @@ struct private_ike_auth_fill_t {
|
|||
|
||||
/** size of non ESP-Marker */
|
||||
#define NON_ESP_MARKER_LEN 4
|
||||
|
||||
/** length of fixed encryption payload header */
|
||||
#define ENCRYPTION_PAYLOAD_HEADER_LENGTH 4
|
||||
/** length of fixed cert payload header */
|
||||
#define CERT_PAYLOAD_HEADER_LENGTH 5
|
||||
/**
|
||||
* Calculate packet size on wire (without ethernet/IP header)
|
||||
*/
|
||||
|
@ -89,9 +92,9 @@ static size_t calculate_wire_size(message_t *message, ike_sa_t *ike_sa)
|
|||
|
||||
METHOD(listener_t, message, bool,
|
||||
private_ike_auth_fill_t *this, ike_sa_t *ike_sa, message_t *message,
|
||||
bool incoming)
|
||||
bool incoming, bool plain)
|
||||
{
|
||||
if (!incoming &&
|
||||
if (!incoming && plain &&
|
||||
message->get_request(message) == this->req &&
|
||||
message->get_message_id(message) == this->id)
|
||||
{
|
||||
|
@ -105,7 +108,7 @@ METHOD(listener_t, message, bool,
|
|||
diff = this->bytes - size - CERT_PAYLOAD_HEADER_LENGTH;
|
||||
data = chunk_alloc(diff);
|
||||
memset(data.ptr, 0x12, data.len);
|
||||
pld = cert_payload_create_custom(201, data);
|
||||
pld = cert_payload_create_custom(CERTIFICATE, 201, data);
|
||||
message->add_payload(message, &pld->payload_interface);
|
||||
DBG1(DBG_CFG, "inserting %d dummy bytes certificate payload", diff);
|
||||
}
|
||||
|
|
|
@ -32,9 +32,9 @@ struct private_log_id_t {
|
|||
|
||||
METHOD(listener_t, message, bool,
|
||||
private_log_id_t *this, ike_sa_t *ike_sa, message_t *message,
|
||||
bool incoming)
|
||||
bool incoming, bool plain)
|
||||
{
|
||||
if (incoming)
|
||||
if (incoming && plain)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
payload_t *payload;
|
||||
|
|
|
@ -32,9 +32,9 @@ struct private_log_ke_t {
|
|||
|
||||
METHOD(listener_t, message, bool,
|
||||
private_log_ke_t *this, ike_sa_t *ike_sa, message_t *message,
|
||||
bool incoming)
|
||||
bool incoming, bool plain)
|
||||
{
|
||||
if (incoming)
|
||||
if (incoming && plain)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
payload_t *payload;
|
||||
|
|
|
@ -32,9 +32,9 @@ struct private_log_proposals_t {
|
|||
|
||||
METHOD(listener_t, message, bool,
|
||||
private_log_proposals_t *this, ike_sa_t *ike_sa, message_t *message,
|
||||
bool incoming)
|
||||
bool incoming, bool plain)
|
||||
{
|
||||
if (incoming)
|
||||
if (incoming && plain)
|
||||
{
|
||||
enumerator_t *enumerator, *proposals;
|
||||
payload_t *payload;
|
||||
|
|
|
@ -32,9 +32,9 @@ struct private_log_ts_t {
|
|||
|
||||
METHOD(listener_t, message, bool,
|
||||
private_log_ts_t *this, ike_sa_t *ike_sa, message_t *message,
|
||||
bool incoming)
|
||||
bool incoming, bool plain)
|
||||
{
|
||||
if (incoming)
|
||||
if (incoming && plain)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
payload_t *payload;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include "hook.h"
|
||||
|
||||
#include <sa/ikev2/keymat_v2.h>
|
||||
#include <encoding/payloads/nonce_payload.h>
|
||||
#include <encoding/payloads/cert_payload.h>
|
||||
#include <encoding/payloads/auth_payload.h>
|
||||
|
@ -135,7 +136,7 @@ static void process_auth_request(private_pretend_auth_t *this,
|
|||
static void process_init_response(private_pretend_auth_t *this,
|
||||
ike_sa_t *ike_sa, message_t *message)
|
||||
{
|
||||
this->ike_init = message->get_packet_data(message);
|
||||
this->ike_init = chunk_clone(message->get_packet_data(message));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -153,7 +154,7 @@ static void build_certs(private_pretend_auth_t *this,
|
|||
cert = auth->get(auth, AUTH_RULE_SUBJECT_CERT);
|
||||
if (cert)
|
||||
{
|
||||
payload = cert_payload_create_from_cert(cert);
|
||||
payload = cert_payload_create_from_cert(CERTIFICATE, cert);
|
||||
if (payload)
|
||||
{
|
||||
DBG1(DBG_IKE, "pretending end entity cert \"%Y\"",
|
||||
|
@ -166,7 +167,7 @@ static void build_certs(private_pretend_auth_t *this,
|
|||
{
|
||||
if (type == AUTH_RULE_IM_CERT)
|
||||
{
|
||||
payload = cert_payload_create_from_cert(cert);
|
||||
payload = cert_payload_create_from_cert(CERTIFICATE, cert);
|
||||
if (payload)
|
||||
{
|
||||
DBG1(DBG_IKE, "pretending issuer cert \"%Y\"",
|
||||
|
@ -190,7 +191,7 @@ static bool build_auth(private_pretend_auth_t *this,
|
|||
auth_payload_t *auth_payload;
|
||||
auth_method_t auth_method;
|
||||
signature_scheme_t scheme;
|
||||
keymat_t *keymat;
|
||||
keymat_v2_t *keymat;
|
||||
|
||||
auth = auth_cfg_create();
|
||||
private = lib->credmgr->get_private(lib->credmgr, KEY_ANY, this->id, auth);
|
||||
|
@ -235,7 +236,7 @@ static bool build_auth(private_pretend_auth_t *this,
|
|||
key_type_names, private->get_type(private));
|
||||
return FALSE;
|
||||
}
|
||||
keymat = ike_sa->get_keymat(ike_sa);
|
||||
keymat = (keymat_v2_t*)ike_sa->get_keymat(ike_sa);
|
||||
octets = keymat->get_auth_octets(keymat, TRUE, this->ike_init,
|
||||
this->nonce, this->id, this->reserved);
|
||||
if (!private->sign(private, scheme, octets, &auth_data))
|
||||
|
@ -294,7 +295,7 @@ static void process_auth_response(private_pretend_auth_t *this,
|
|||
if (this->proposal)
|
||||
{
|
||||
message->add_payload(message, (payload_t*)
|
||||
sa_payload_create_from_proposal(this->proposal));
|
||||
sa_payload_create_from_proposal_v2(this->proposal));
|
||||
}
|
||||
if (this->tsi)
|
||||
{
|
||||
|
@ -310,35 +311,38 @@ static void process_auth_response(private_pretend_auth_t *this,
|
|||
|
||||
METHOD(listener_t, message, bool,
|
||||
private_pretend_auth_t *this, ike_sa_t *ike_sa, message_t *message,
|
||||
bool incoming)
|
||||
bool incoming, bool plain)
|
||||
{
|
||||
if (incoming)
|
||||
if (plain)
|
||||
{
|
||||
if (!message->get_request(message))
|
||||
if (incoming)
|
||||
{
|
||||
if (message->get_exchange_type(message) == IKE_SA_INIT)
|
||||
if (!message->get_request(message))
|
||||
{
|
||||
process_init_response(this, ike_sa, message);
|
||||
}
|
||||
if (message->get_exchange_type(message) == IKE_AUTH &&
|
||||
message->get_message_id(message) == 1)
|
||||
{
|
||||
process_auth_response(this, ike_sa, message);
|
||||
if (message->get_exchange_type(message) == IKE_SA_INIT)
|
||||
{
|
||||
process_init_response(this, ike_sa, message);
|
||||
}
|
||||
if (message->get_exchange_type(message) == IKE_AUTH &&
|
||||
message->get_message_id(message) == 1)
|
||||
{
|
||||
process_auth_response(this, ike_sa, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (message->get_request(message))
|
||||
else
|
||||
{
|
||||
if (message->get_exchange_type(message) == IKE_SA_INIT)
|
||||
if (message->get_request(message))
|
||||
{
|
||||
process_init_request(this, ike_sa, message);
|
||||
}
|
||||
if (message->get_exchange_type(message) == IKE_AUTH &&
|
||||
message->get_message_id(message) == 1)
|
||||
{
|
||||
process_auth_request(this, ike_sa, message);
|
||||
if (message->get_exchange_type(message) == IKE_SA_INIT)
|
||||
{
|
||||
process_init_request(this, ike_sa, message);
|
||||
}
|
||||
if (message->get_exchange_type(message) == IKE_AUTH &&
|
||||
message->get_message_id(message) == 1)
|
||||
{
|
||||
process_auth_request(this, ike_sa, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include "hook.h"
|
||||
|
||||
#include <sa/ikev2/keymat_v2.h>
|
||||
#include <encoding/generator.h>
|
||||
#include <encoding/payloads/nonce_payload.h>
|
||||
#include <encoding/payloads/auth_payload.h>
|
||||
|
@ -57,12 +58,11 @@ static bool rebuild_auth(private_rebuild_auth_t *this, ike_sa_t *ike_sa,
|
|||
enumerator_t *enumerator;
|
||||
chunk_t octets, auth_data;
|
||||
private_key_t *private;
|
||||
auth_cfg_t *auth;
|
||||
payload_t *payload;
|
||||
auth_payload_t *auth_payload;
|
||||
auth_method_t auth_method;
|
||||
signature_scheme_t scheme;
|
||||
keymat_t *keymat;
|
||||
keymat_v2_t *keymat;
|
||||
identification_t *id;
|
||||
char reserved[3];
|
||||
generator_t *generator;
|
||||
|
@ -90,10 +90,8 @@ static bool rebuild_auth(private_rebuild_auth_t *this, ike_sa_t *ike_sa,
|
|||
id = identification_create_from_encoding(data.ptr[4], chunk_skip(data, 8));
|
||||
generator->destroy(generator);
|
||||
|
||||
auth = auth_cfg_create();
|
||||
private = lib->credmgr->get_private(lib->credmgr, KEY_ANY,
|
||||
this->id ?: id, auth);
|
||||
auth->destroy(auth);
|
||||
this->id ?: id, NULL);
|
||||
if (private == NULL)
|
||||
{
|
||||
DBG1(DBG_CFG, "no private key found for '%Y' to rebuild AUTH",
|
||||
|
@ -137,7 +135,7 @@ static bool rebuild_auth(private_rebuild_auth_t *this, ike_sa_t *ike_sa,
|
|||
id->destroy(id);
|
||||
return FALSE;
|
||||
}
|
||||
keymat = ike_sa->get_keymat(ike_sa);
|
||||
keymat = (keymat_v2_t*)ike_sa->get_keymat(ike_sa);
|
||||
octets = keymat->get_auth_octets(keymat, FALSE, this->ike_init,
|
||||
this->nonce, id, reserved);
|
||||
if (!private->sign(private, scheme, octets, &auth_data))
|
||||
|
@ -174,34 +172,37 @@ static bool rebuild_auth(private_rebuild_auth_t *this, ike_sa_t *ike_sa,
|
|||
|
||||
METHOD(listener_t, message, bool,
|
||||
private_rebuild_auth_t *this, ike_sa_t *ike_sa, message_t *message,
|
||||
bool incoming)
|
||||
bool incoming, bool plain)
|
||||
{
|
||||
if (!incoming && message->get_message_id(message) == 1)
|
||||
if (plain)
|
||||
{
|
||||
rebuild_auth(this, ike_sa, message);
|
||||
}
|
||||
if (message->get_exchange_type(message) == IKE_SA_INIT)
|
||||
{
|
||||
if (incoming)
|
||||
if (!incoming && message->get_message_id(message) == 1)
|
||||
{
|
||||
nonce_payload_t *nonce;
|
||||
|
||||
nonce = (nonce_payload_t*)message->get_payload(message, NONCE);
|
||||
if (nonce)
|
||||
{
|
||||
free(this->nonce.ptr);
|
||||
this->nonce = nonce->get_nonce(nonce);
|
||||
}
|
||||
rebuild_auth(this, ike_sa, message);
|
||||
}
|
||||
else
|
||||
if (message->get_exchange_type(message) == IKE_SA_INIT)
|
||||
{
|
||||
packet_t *packet;
|
||||
|
||||
if (message->generate(message, NULL, &packet) == SUCCESS)
|
||||
if (incoming)
|
||||
{
|
||||
free(this->ike_init.ptr);
|
||||
this->ike_init = chunk_clone(packet->get_data(packet));
|
||||
packet->destroy(packet);
|
||||
nonce_payload_t *nonce;
|
||||
|
||||
nonce = (nonce_payload_t*)message->get_payload(message, NONCE);
|
||||
if (nonce)
|
||||
{
|
||||
free(this->nonce.ptr);
|
||||
this->nonce = nonce->get_nonce(nonce);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
packet_t *packet;
|
||||
|
||||
if (message->generate(message, NULL, &packet) == SUCCESS)
|
||||
{
|
||||
free(this->ike_init.ptr);
|
||||
this->ike_init = chunk_clone(packet->get_data(packet));
|
||||
packet->destroy(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,9 +47,9 @@ struct private_set_critical_t {
|
|||
|
||||
METHOD(listener_t, message, bool,
|
||||
private_set_critical_t *this, ike_sa_t *ike_sa, message_t *message,
|
||||
bool incoming)
|
||||
bool incoming, bool plain)
|
||||
{
|
||||
if (!incoming &&
|
||||
if (!incoming && plain &&
|
||||
message->get_request(message) == this->req &&
|
||||
message->get_message_id(message) == this->id)
|
||||
{
|
||||
|
|
|
@ -42,9 +42,9 @@ struct private_set_ike_initiator_t {
|
|||
|
||||
METHOD(listener_t, message, bool,
|
||||
private_set_ike_initiator_t *this, ike_sa_t *ike_sa, message_t *message,
|
||||
bool incoming)
|
||||
bool incoming, bool plain)
|
||||
{
|
||||
if (!incoming &&
|
||||
if (!incoming && plain &&
|
||||
message->get_request(message) == this->req &&
|
||||
message->get_message_id(message) == this->id)
|
||||
{
|
||||
|
|
|
@ -42,9 +42,9 @@ struct private_set_ike_request_t {
|
|||
|
||||
METHOD(listener_t, message, bool,
|
||||
private_set_ike_request_t *this, ike_sa_t *ike_sa, message_t *message,
|
||||
bool incoming)
|
||||
bool incoming, bool plain)
|
||||
{
|
||||
if (!incoming &&
|
||||
if (!incoming && plain &&
|
||||
message->get_request(message) == this->req &&
|
||||
message->get_message_id(message) == this->id)
|
||||
{
|
||||
|
|
|
@ -52,9 +52,9 @@ struct private_set_ike_spi_t {
|
|||
|
||||
METHOD(listener_t, message, bool,
|
||||
private_set_ike_spi_t *this, ike_sa_t *ike_sa, message_t *message,
|
||||
bool incoming)
|
||||
bool incoming, bool plain)
|
||||
{
|
||||
if (!incoming &&
|
||||
if (!incoming && plain &&
|
||||
message->get_request(message) == this->req &&
|
||||
message->get_message_id(message) == this->id)
|
||||
{
|
||||
|
|
|
@ -57,9 +57,9 @@ struct private_set_ike_version_t {
|
|||
|
||||
METHOD(listener_t, message, bool,
|
||||
private_set_ike_version_t *this, ike_sa_t *ike_sa, message_t *message,
|
||||
bool incoming)
|
||||
bool incoming, bool plain)
|
||||
{
|
||||
if (!incoming &&
|
||||
if (!incoming && plain &&
|
||||
message->get_request(message) == this->req &&
|
||||
message->get_message_id(message) == this->id)
|
||||
{
|
||||
|
|
|
@ -50,9 +50,9 @@ struct private_set_length_t {
|
|||
|
||||
METHOD(listener_t, message, bool,
|
||||
private_set_length_t *this, ike_sa_t *ike_sa, message_t *message,
|
||||
bool incoming)
|
||||
bool incoming, bool plain)
|
||||
{
|
||||
if (!incoming &&
|
||||
if (!incoming && plain &&
|
||||
message->get_request(message) == this->req &&
|
||||
message->get_message_id(message) == this->id)
|
||||
{
|
||||
|
@ -76,11 +76,10 @@ METHOD(listener_t, message, bool,
|
|||
if (type == payload->get_type(payload))
|
||||
{
|
||||
encoding_rule_t *rules;
|
||||
size_t count;
|
||||
u_int16_t *len;
|
||||
int i;
|
||||
int i, count;
|
||||
|
||||
payload->get_encoding_rules(payload, &rules, &count);
|
||||
count = payload->get_encoding_rules(payload, &rules);
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if (rules[i].type == PAYLOAD_LENGTH)
|
||||
|
|
|
@ -69,9 +69,9 @@ static void copy_proposal_algs(proposal_t *from, proposal_t *to,
|
|||
|
||||
METHOD(listener_t, message, bool,
|
||||
private_set_proposal_number_t *this, ike_sa_t *ike_sa, message_t *message,
|
||||
bool incoming)
|
||||
bool incoming, bool plain)
|
||||
{
|
||||
if (!incoming &&
|
||||
if (!incoming && plain &&
|
||||
message->get_request(message) == this->req &&
|
||||
message->get_message_id(message) == this->id)
|
||||
{
|
||||
|
@ -121,7 +121,7 @@ METHOD(listener_t, message, bool,
|
|||
}
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
sa = sa_payload_create_from_proposal_list(updated);
|
||||
sa = sa_payload_create_from_proposals_v2(updated);
|
||||
list->destroy_offset(list, offsetof(proposal_t, destroy));
|
||||
updated->destroy_offset(updated, offsetof(proposal_t, destroy));
|
||||
message->add_payload(message, (payload_t*)sa);
|
||||
|
|
|
@ -163,9 +163,9 @@ static void set_byte(private_set_reserved_t *this, message_t *message,
|
|||
|
||||
METHOD(listener_t, message, bool,
|
||||
private_set_reserved_t *this, ike_sa_t *ike_sa, message_t *message,
|
||||
bool incoming)
|
||||
bool incoming, bool plain)
|
||||
{
|
||||
if (!incoming &&
|
||||
if (!incoming && plain &&
|
||||
message->get_request(message) == this->req &&
|
||||
message->get_message_id(message) == this->id)
|
||||
{
|
||||
|
|
|
@ -84,7 +84,7 @@ METHOD(listener_t, ike_updown, bool,
|
|||
{
|
||||
data = chunk_clone(chunk_create(this->data, strlen(this->data)));
|
||||
}
|
||||
notify = notify_payload_create_from_protocol_and_type(
|
||||
notify = notify_payload_create_from_protocol_and_type(NOTIFY,
|
||||
this->esp ? PROTO_ESP : PROTO_IKE, type);
|
||||
notify->set_spi(notify, this->spi);
|
||||
if (data.len)
|
||||
|
@ -95,7 +95,7 @@ METHOD(listener_t, ike_updown, bool,
|
|||
|
||||
DBG1(DBG_CFG, "injecting unencrypted INFORMATIONAL message");
|
||||
|
||||
message = message_create();
|
||||
message = message_create(IKEV2_MAJOR_VERSION, IKEV2_MINOR_VERSION);
|
||||
message->set_message_id(message, this->id);
|
||||
message->set_ike_sa_id(message, ike_sa->get_id(ike_sa));
|
||||
message->set_exchange_type(message, INFORMATIONAL);
|
||||
|
|
|
@ -45,9 +45,9 @@ struct private_unsort_message_t {
|
|||
|
||||
METHOD(listener_t, message, bool,
|
||||
private_unsort_message_t *this, ike_sa_t *ike_sa, message_t *message,
|
||||
bool incoming)
|
||||
bool incoming, bool plain)
|
||||
{
|
||||
if (!incoming &&
|
||||
if (!incoming && plain &&
|
||||
message->get_request(message) == this->req &&
|
||||
message->get_message_id(message) == this->id)
|
||||
{
|
||||
|
|
|
@ -38,6 +38,7 @@ encoding/payloads/transform_substructure.c encoding/payloads/transform_substruct
|
|||
encoding/payloads/ts_payload.c encoding/payloads/ts_payload.h \
|
||||
encoding/payloads/unknown_payload.c encoding/payloads/unknown_payload.h \
|
||||
encoding/payloads/vendor_id_payload.c encoding/payloads/vendor_id_payload.h \
|
||||
encoding/payloads/hash_payload.c encoding/payloads/hash_payload.h \
|
||||
kernel/kernel_handler.c kernel/kernel_handler.h \
|
||||
network/receiver.c network/receiver.h network/sender.c network/sender.h \
|
||||
network/packet.c network/packet.h network/socket.c network/socket.h \
|
||||
|
@ -56,37 +57,70 @@ processing/jobs/start_action_job.c processing/jobs/start_action_job.h \
|
|||
processing/jobs/roam_job.c processing/jobs/roam_job.h \
|
||||
processing/jobs/update_sa_job.c processing/jobs/update_sa_job.h \
|
||||
processing/jobs/inactivity_job.c processing/jobs/inactivity_job.h \
|
||||
sa/authenticators/authenticator.c sa/authenticators/authenticator.h \
|
||||
sa/authenticators/eap_authenticator.c sa/authenticators/eap_authenticator.h \
|
||||
sa/authenticators/eap/eap_method.c sa/authenticators/eap/eap_method.h \
|
||||
sa/authenticators/eap/eap_manager.c sa/authenticators/eap/eap_manager.h \
|
||||
sa/authenticators/psk_authenticator.c sa/authenticators/psk_authenticator.h \
|
||||
sa/authenticators/pubkey_authenticator.c sa/authenticators/pubkey_authenticator.h \
|
||||
sa/eap/eap_method.c sa/eap/eap_method.h \
|
||||
sa/eap/eap_manager.c sa/eap/eap_manager.h \
|
||||
sa/xauth/xauth_method.c sa/xauth/xauth_method.h \
|
||||
sa/xauth/xauth_manager.c sa/xauth/xauth_manager.h \
|
||||
sa/authenticator.c sa/authenticator.h \
|
||||
sa/child_sa.c sa/child_sa.h \
|
||||
sa/ike_sa.c sa/ike_sa.h \
|
||||
sa/ike_sa_id.c sa/ike_sa_id.h \
|
||||
sa/keymat.h sa/keymat.c \
|
||||
sa/ike_sa_manager.c sa/ike_sa_manager.h \
|
||||
sa/task_manager.c sa/task_manager.h \
|
||||
sa/keymat.c sa/keymat.h \
|
||||
sa/task_manager.h sa/task_manager.c \
|
||||
sa/shunt_manager.c sa/shunt_manager.h \
|
||||
sa/trap_manager.c sa/trap_manager.h \
|
||||
sa/tasks/child_create.c sa/tasks/child_create.h \
|
||||
sa/tasks/child_delete.c sa/tasks/child_delete.h \
|
||||
sa/tasks/child_rekey.c sa/tasks/child_rekey.h \
|
||||
sa/tasks/ike_auth.c sa/tasks/ike_auth.h \
|
||||
sa/tasks/ike_cert_pre.c sa/tasks/ike_cert_pre.h \
|
||||
sa/tasks/ike_cert_post.c sa/tasks/ike_cert_post.h \
|
||||
sa/tasks/ike_config.c sa/tasks/ike_config.h \
|
||||
sa/tasks/ike_delete.c sa/tasks/ike_delete.h \
|
||||
sa/tasks/ike_dpd.c sa/tasks/ike_dpd.h \
|
||||
sa/tasks/ike_init.c sa/tasks/ike_init.h \
|
||||
sa/tasks/ike_natd.c sa/tasks/ike_natd.h \
|
||||
sa/tasks/ike_mobike.c sa/tasks/ike_mobike.h \
|
||||
sa/tasks/ike_rekey.c sa/tasks/ike_rekey.h \
|
||||
sa/tasks/ike_reauth.c sa/tasks/ike_reauth.h \
|
||||
sa/tasks/ike_auth_lifetime.c sa/tasks/ike_auth_lifetime.h \
|
||||
sa/tasks/ike_vendor.c sa/tasks/ike_vendor.h \
|
||||
sa/tasks/task.c sa/tasks/task.h
|
||||
sa/task.c sa/task.h
|
||||
|
||||
if USE_IKEV2
|
||||
libcharon_la_SOURCES += \
|
||||
sa/ikev2/keymat_v2.c sa/ikev2/keymat_v2.h \
|
||||
sa/ikev2/task_manager_v2.c sa/ikev2/task_manager_v2.h \
|
||||
sa/ikev2/authenticators/eap_authenticator.c sa/ikev2/authenticators/eap_authenticator.h \
|
||||
sa/ikev2/authenticators/psk_authenticator.c sa/ikev2/authenticators/psk_authenticator.h \
|
||||
sa/ikev2/authenticators/pubkey_authenticator.c sa/ikev2/authenticators/pubkey_authenticator.h \
|
||||
sa/ikev2/tasks/child_create.c sa/ikev2/tasks/child_create.h \
|
||||
sa/ikev2/tasks/child_delete.c sa/ikev2/tasks/child_delete.h \
|
||||
sa/ikev2/tasks/child_rekey.c sa/ikev2/tasks/child_rekey.h \
|
||||
sa/ikev2/tasks/ike_auth.c sa/ikev2/tasks/ike_auth.h \
|
||||
sa/ikev2/tasks/ike_cert_pre.c sa/ikev2/tasks/ike_cert_pre.h \
|
||||
sa/ikev2/tasks/ike_cert_post.c sa/ikev2/tasks/ike_cert_post.h \
|
||||
sa/ikev2/tasks/ike_config.c sa/ikev2/tasks/ike_config.h \
|
||||
sa/ikev2/tasks/ike_delete.c sa/ikev2/tasks/ike_delete.h \
|
||||
sa/ikev2/tasks/ike_dpd.c sa/ikev2/tasks/ike_dpd.h \
|
||||
sa/ikev2/tasks/ike_init.c sa/ikev2/tasks/ike_init.h \
|
||||
sa/ikev2/tasks/ike_natd.c sa/ikev2/tasks/ike_natd.h \
|
||||
sa/ikev2/tasks/ike_mobike.c sa/ikev2/tasks/ike_mobike.h \
|
||||
sa/ikev2/tasks/ike_rekey.c sa/ikev2/tasks/ike_rekey.h \
|
||||
sa/ikev2/tasks/ike_reauth.c sa/ikev2/tasks/ike_reauth.h \
|
||||
sa/ikev2/tasks/ike_auth_lifetime.c sa/ikev2/tasks/ike_auth_lifetime.h \
|
||||
sa/ikev2/tasks/ike_vendor.c sa/ikev2/tasks/ike_vendor.h
|
||||
endif
|
||||
|
||||
if USE_IKEV1
|
||||
libcharon_la_SOURCES += \
|
||||
sa/ikev1/keymat_v1.c sa/ikev1/keymat_v1.h \
|
||||
sa/ikev1/task_manager_v1.c sa/ikev1/task_manager_v1.h \
|
||||
sa/ikev1/authenticators/psk_v1_authenticator.c sa/ikev1/authenticators/psk_v1_authenticator.h \
|
||||
sa/ikev1/authenticators/pubkey_v1_authenticator.c sa/ikev1/authenticators/pubkey_v1_authenticator.h \
|
||||
sa/ikev1/authenticators/hybrid_authenticator.c sa/ikev1/authenticators/hybrid_authenticator.h \
|
||||
sa/ikev1/phase1.c sa/ikev1/phase1.h \
|
||||
sa/ikev1/tasks/main_mode.c sa/ikev1/tasks/main_mode.h \
|
||||
sa/ikev1/tasks/aggressive_mode.c sa/ikev1/tasks/aggressive_mode.h \
|
||||
sa/ikev1/tasks/informational.c sa/ikev1/tasks/informational.h \
|
||||
sa/ikev1/tasks/isakmp_cert_pre.c sa/ikev1/tasks/isakmp_cert_pre.h \
|
||||
sa/ikev1/tasks/isakmp_cert_post.c sa/ikev1/tasks/isakmp_cert_post.h \
|
||||
sa/ikev1/tasks/isakmp_natd.c sa/ikev1/tasks/isakmp_natd.h \
|
||||
sa/ikev1/tasks/isakmp_vendor.c sa/ikev1/tasks/isakmp_vendor.h \
|
||||
sa/ikev1/tasks/isakmp_delete.c sa/ikev1/tasks/isakmp_delete.h \
|
||||
sa/ikev1/tasks/isakmp_dpd.c sa/ikev1/tasks/isakmp_dpd.h \
|
||||
sa/ikev1/tasks/xauth.c sa/ikev1/tasks/xauth.h \
|
||||
sa/ikev1/tasks/quick_mode.c sa/ikev1/tasks/quick_mode.h \
|
||||
sa/ikev1/tasks/quick_delete.c sa/ikev1/tasks/quick_delete.h \
|
||||
sa/ikev1/tasks/mode_config.c sa/ikev1/tasks/mode_config.h \
|
||||
processing/jobs/adopt_children_job.c processing/jobs/adopt_children_job.h
|
||||
endif
|
||||
|
||||
|
||||
daemon.lo : $(top_builddir)/config.status
|
||||
|
||||
|
@ -112,9 +146,9 @@ if USE_ME
|
|||
libcharon_la_SOURCES += encoding/payloads/endpoint_notify.c encoding/payloads/endpoint_notify.h \
|
||||
processing/jobs/initiate_mediation_job.c processing/jobs/initiate_mediation_job.h \
|
||||
processing/jobs/mediation_job.c processing/jobs/mediation_job.h \
|
||||
sa/connect_manager.c sa/connect_manager.h \
|
||||
sa/mediation_manager.c sa/mediation_manager.h \
|
||||
sa/tasks/ike_me.c sa/tasks/ike_me.h
|
||||
sa/ikev2/connect_manager.c sa/ikev2/connect_manager.h \
|
||||
sa/ikev2/mediation_manager.c sa/ikev2/mediation_manager.h \
|
||||
sa/ikev2/tasks/ike_me.c sa/ikev2/tasks/ike_me.h
|
||||
endif
|
||||
|
||||
if USE_LIBCAP
|
||||
|
@ -508,3 +542,16 @@ if MONOLITHIC
|
|||
endif
|
||||
endif
|
||||
|
||||
if USE_XAUTH_GENERIC
|
||||
SUBDIRS += plugins/xauth_generic
|
||||
if MONOLITHIC
|
||||
libcharon_la_LIBADD += plugins/xauth_generic/libstrongswan-xauth-generic.la
|
||||
endif
|
||||
endif
|
||||
|
||||
if USE_XAUTH_EAP
|
||||
SUBDIRS += plugins/xauth_eap
|
||||
if MONOLITHIC
|
||||
libcharon_la_LIBADD += plugins/xauth_eap/libstrongswan-xauth-eap.la
|
||||
endif
|
||||
endif
|
||||
|
|
|
@ -406,7 +406,7 @@ METHOD(bus_t, child_state_change, void,
|
|||
}
|
||||
|
||||
METHOD(bus_t, message, void,
|
||||
private_bus_t *this, message_t *message, bool incoming)
|
||||
private_bus_t *this, message_t *message, bool incoming, bool plain)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
ike_sa_t *ike_sa;
|
||||
|
@ -425,7 +425,7 @@ METHOD(bus_t, message, void,
|
|||
}
|
||||
entry->calling++;
|
||||
keep = entry->listener->message(entry->listener, ike_sa,
|
||||
message, incoming);
|
||||
message, incoming, plain);
|
||||
entry->calling--;
|
||||
if (!keep)
|
||||
{
|
||||
|
@ -438,7 +438,8 @@ METHOD(bus_t, message, void,
|
|||
|
||||
METHOD(bus_t, ike_keys, void,
|
||||
private_bus_t *this, ike_sa_t *ike_sa, diffie_hellman_t *dh,
|
||||
chunk_t nonce_i, chunk_t nonce_r, ike_sa_t *rekey)
|
||||
chunk_t dh_other, chunk_t nonce_i, chunk_t nonce_r,
|
||||
ike_sa_t *rekey, shared_key_t *shared)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
entry_t *entry;
|
||||
|
@ -453,8 +454,8 @@ METHOD(bus_t, ike_keys, void,
|
|||
continue;
|
||||
}
|
||||
entry->calling++;
|
||||
keep = entry->listener->ike_keys(entry->listener, ike_sa, dh,
|
||||
nonce_i, nonce_r, rekey);
|
||||
keep = entry->listener->ike_keys(entry->listener, ike_sa, dh, dh_other,
|
||||
nonce_i, nonce_r, rekey, shared);
|
||||
entry->calling--;
|
||||
if (!keep)
|
||||
{
|
||||
|
|
|
@ -235,10 +235,15 @@ struct bus_t {
|
|||
/**
|
||||
* Message send/receive hook.
|
||||
*
|
||||
* The hook is invoked twice for each message: Once with plain, parsed data
|
||||
* and once encoded and encrypted.
|
||||
*
|
||||
* @param message message to send/receive
|
||||
* @param incoming TRUE for incoming messages, FALSE for outgoing
|
||||
* @param plain TRUE if message is parsed and decrypted, FALSE it not
|
||||
* @param
|
||||
*/
|
||||
void (*message)(bus_t *this, message_t *message, bool incoming);
|
||||
void (*message)(bus_t *this, message_t *message, bool incoming, bool plain);
|
||||
|
||||
/**
|
||||
* IKE_SA authorization hook.
|
||||
|
@ -264,12 +269,15 @@ struct bus_t {
|
|||
*
|
||||
* @param ike_sa IKE_SA this keymat belongs to
|
||||
* @param dh diffie hellman shared secret
|
||||
* @param dh_other others DH public value (IKEv1 only)
|
||||
* @param nonce_i initiators nonce
|
||||
* @param nonce_r responders nonce
|
||||
* @param rekey IKE_SA we are rekeying, if any
|
||||
* @param rekey IKE_SA we are rekeying, if any (IKEv2 only)
|
||||
* @param shared shared key used for key derivation (IKEv1-PSK only)
|
||||
*/
|
||||
void (*ike_keys)(bus_t *this, ike_sa_t *ike_sa, diffie_hellman_t *dh,
|
||||
chunk_t nonce_i, chunk_t nonce_r, ike_sa_t *rekey);
|
||||
chunk_t dh_other, chunk_t nonce_i, chunk_t nonce_r,
|
||||
ike_sa_t *rekey, shared_key_t *shared);
|
||||
/**
|
||||
* CHILD_SA keymat hook.
|
||||
*
|
||||
|
|
|
@ -84,26 +84,33 @@ struct listener_t {
|
|||
/**
|
||||
* Hook called for received/sent messages of an IKE_SA.
|
||||
*
|
||||
* The hook is invoked twice for each message: Once with plain, parsed data
|
||||
* and once encoded and encrypted.
|
||||
*
|
||||
* @param ike_sa IKE_SA sending/receiving a message
|
||||
* @param message message object
|
||||
* @param incoming TRUE for incoming messages, FALSE for outgoing
|
||||
* @param plain TRUE if message is parsed and decrypted, FALSE it not
|
||||
* @return TRUE to stay registered, FALSE to unregister
|
||||
*/
|
||||
bool (*message)(listener_t *this, ike_sa_t *ike_sa, message_t *message,
|
||||
bool incoming);
|
||||
bool incoming, bool plain);
|
||||
|
||||
/**
|
||||
* Hook called with IKE_SA key material.
|
||||
*
|
||||
* @param ike_sa IKE_SA this keymat belongs to
|
||||
* @param dh diffie hellman shared secret
|
||||
* @param dh_other others DH public value (IKEv1 only)
|
||||
* @param nonce_i initiators nonce
|
||||
* @param nonce_r responders nonce
|
||||
* @param rekey IKE_SA we are rekeying, if any
|
||||
* @param rekey IKE_SA we are rekeying, if any (IKEv2 only)
|
||||
* @param shared shared key used for key derivation (IKEv1-PSK only)
|
||||
* @return TRUE to stay registered, FALSE to unregister
|
||||
*/
|
||||
bool (*ike_keys)(listener_t *this, ike_sa_t *ike_sa, diffie_hellman_t *dh,
|
||||
chunk_t nonce_i, chunk_t nonce_r, ike_sa_t *rekey);
|
||||
chunk_t dh_other, chunk_t nonce_i, chunk_t nonce_r,
|
||||
ike_sa_t *rekey, shared_key_t *shared);
|
||||
|
||||
/**
|
||||
* Hook called with CHILD_SA key material.
|
||||
|
|
|
@ -146,10 +146,11 @@ METHOD(backend_manager_t, get_ike_cfg, ike_cfg_t*,
|
|||
ike_cfg_match_t match, best = MATCH_ANY;
|
||||
ike_data_t *data;
|
||||
|
||||
data = malloc_thing(ike_data_t);
|
||||
data->this = this;
|
||||
data->me = me;
|
||||
data->other = other;
|
||||
INIT(data,
|
||||
.this = this,
|
||||
.me = me,
|
||||
.other = other,
|
||||
);
|
||||
|
||||
DBG2(DBG_CFG, "looking for an ike config for %H...%H", me, other);
|
||||
|
||||
|
@ -160,7 +161,7 @@ METHOD(backend_manager_t, get_ike_cfg, ike_cfg_t*,
|
|||
while (enumerator->enumerate(enumerator, (void**)¤t))
|
||||
{
|
||||
match = get_ike_match(current, me, other);
|
||||
|
||||
DBG3(DBG_CFG, "ike config match: %d (%H %H)", match, me, other);
|
||||
if (match)
|
||||
{
|
||||
DBG2(DBG_CFG, " candidate: %s...%s, prio %d",
|
||||
|
@ -195,9 +196,13 @@ static id_match_t get_peer_match(identification_t *id,
|
|||
auth_cfg_t *auth;
|
||||
identification_t *candidate;
|
||||
id_match_t match = ID_MATCH_NONE;
|
||||
char *where = local ? "local" : "remote";
|
||||
chunk_t data;
|
||||
|
||||
if (!id)
|
||||
{
|
||||
DBG3(DBG_CFG, "peer config match %s: %d (%N)",
|
||||
where, ID_MATCH_ANY, id_type_names, ID_ANY);
|
||||
return ID_MATCH_ANY;
|
||||
}
|
||||
|
||||
|
@ -221,9 +226,29 @@ static id_match_t get_peer_match(identification_t *id,
|
|||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
data = id->get_encoding(id);
|
||||
DBG3(DBG_CFG, "peer config match %s: %d (%N -> %#B)",
|
||||
where, match, id_type_names, id->get_type(id), &data);
|
||||
return match;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get match quality of IKE version
|
||||
*/
|
||||
static int get_version_match(ike_version_t cfg, ike_version_t req)
|
||||
{
|
||||
if (req == IKE_ANY || cfg == IKE_ANY)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (req == cfg)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* data to pass nested peer enumerator
|
||||
*/
|
||||
|
@ -317,17 +342,18 @@ static void insert_sorted(match_entry_t *entry, linked_list_t *list,
|
|||
|
||||
METHOD(backend_manager_t, create_peer_cfg_enumerator, enumerator_t*,
|
||||
private_backend_manager_t *this, host_t *me, host_t *other,
|
||||
identification_t *my_id, identification_t *other_id)
|
||||
identification_t *my_id, identification_t *other_id, ike_version_t version)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
peer_data_t *data;
|
||||
peer_cfg_t *cfg;
|
||||
linked_list_t *configs, *helper;
|
||||
|
||||
data = malloc_thing(peer_data_t);
|
||||
data->lock = this->lock;
|
||||
data->me = my_id;
|
||||
data->other = other_id;
|
||||
INIT(data,
|
||||
.lock = this->lock,
|
||||
.me = my_id,
|
||||
.other = other_id,
|
||||
);
|
||||
|
||||
/* create a sorted list with all matches */
|
||||
this->lock->read_lock(this->lock);
|
||||
|
@ -340,9 +366,6 @@ METHOD(backend_manager_t, create_peer_cfg_enumerator, enumerator_t*,
|
|||
return enumerator;
|
||||
}
|
||||
|
||||
DBG1(DBG_CFG, "looking for peer configs matching %H[%Y]...%H[%Y]",
|
||||
me, my_id, other, other_id);
|
||||
|
||||
configs = linked_list_create();
|
||||
/* only once allocated helper list for sorting */
|
||||
helper = linked_list_create();
|
||||
|
@ -350,29 +373,26 @@ METHOD(backend_manager_t, create_peer_cfg_enumerator, enumerator_t*,
|
|||
{
|
||||
id_match_t match_peer_me, match_peer_other;
|
||||
ike_cfg_match_t match_ike;
|
||||
int match_version;
|
||||
match_entry_t *entry;
|
||||
chunk_t data;
|
||||
|
||||
match_peer_me = get_peer_match(my_id, cfg, TRUE);
|
||||
data = my_id->get_encoding(my_id);
|
||||
DBG3(DBG_CFG, "match_peer_me: %d (%N -> %#B)", match_peer_me,
|
||||
id_type_names, my_id->get_type(my_id), &data);
|
||||
match_peer_other = get_peer_match(other_id, cfg, FALSE);
|
||||
data = other_id->get_encoding(other_id);
|
||||
DBG3(DBG_CFG, "match_peer_other: %d (%N -> %#B)", match_peer_other,
|
||||
id_type_names, other_id->get_type(other_id), &data);
|
||||
match_ike = get_ike_match(cfg->get_ike_cfg(cfg), me, other);
|
||||
DBG3(DBG_CFG, "match_ike: %d (%H %H)", match_ike, me, other);
|
||||
match_version = get_version_match(cfg->get_ike_version(cfg), version);
|
||||
DBG3(DBG_CFG, "ike config match: %d (%H %H)", match_ike, me, other);
|
||||
|
||||
if (match_peer_me && match_peer_other && match_ike)
|
||||
if (match_peer_me && match_peer_other && match_ike && match_version)
|
||||
{
|
||||
DBG2(DBG_CFG, " candidate \"%s\", match: %d/%d/%d (me/other/ike)",
|
||||
cfg->get_name(cfg), match_peer_me, match_peer_other, match_ike);
|
||||
DBG2(DBG_CFG, " candidate \"%s\", match: %d/%d/%d/%d "
|
||||
"(me/other/ike/version)", cfg->get_name(cfg),
|
||||
match_peer_me, match_peer_other, match_ike, match_version);
|
||||
|
||||
entry = malloc_thing(match_entry_t);
|
||||
entry->match_peer = match_peer_me + match_peer_other;
|
||||
entry->match_ike = match_ike;
|
||||
entry->cfg = cfg->get_ref(cfg);
|
||||
INIT(entry,
|
||||
.match_peer = match_peer_me + match_peer_other,
|
||||
.match_ike = match_ike,
|
||||
.cfg = cfg->get_ref(cfg),
|
||||
);
|
||||
insert_sorted(entry, configs, helper);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@ struct backend_manager_t {
|
|||
*
|
||||
* @param my_host address of own host
|
||||
* @param other_host address of remote host
|
||||
* @param version IKE version to get a config for
|
||||
* @return matching ike_config, or NULL if none found
|
||||
*/
|
||||
ike_cfg_t* (*get_ike_cfg)(backend_manager_t *this,
|
||||
|
@ -79,11 +80,12 @@ struct backend_manager_t {
|
|||
* @param other remote address
|
||||
* @param my_id IDr in first authentication round
|
||||
* @param other_id IDi in first authentication round
|
||||
* @param version IKE version to get a config for
|
||||
* @return enumerator over peer_cfg_t
|
||||
*/
|
||||
enumerator_t* (*create_peer_cfg_enumerator)(backend_manager_t *this,
|
||||
host_t *me, host_t *other, identification_t *my_id,
|
||||
identification_t *other_id);
|
||||
identification_t *other_id, ike_version_t version);
|
||||
/**
|
||||
* Register a backend on the manager.
|
||||
*
|
||||
|
|
|
@ -25,6 +25,12 @@
|
|||
#include <utils/linked_list.h>
|
||||
#include <utils/identification.h>
|
||||
|
||||
ENUM(ike_version_names, IKE_ANY, IKEV2,
|
||||
"IKEv1/2",
|
||||
"IKEv1",
|
||||
"IKEv2",
|
||||
);
|
||||
|
||||
ENUM(cert_policy_names, CERT_ALWAYS_SEND, CERT_NEVER_SEND,
|
||||
"CERT_ALWAYS_SEND",
|
||||
"CERT_SEND_IF_ASKED",
|
||||
|
@ -62,7 +68,7 @@ struct private_peer_cfg_t {
|
|||
/**
|
||||
* IKE version to use for initiation
|
||||
*/
|
||||
u_int ike_version;
|
||||
ike_version_t ike_version;
|
||||
|
||||
/**
|
||||
* IKE config associated to this peer config
|
||||
|
@ -99,6 +105,11 @@ struct private_peer_cfg_t {
|
|||
*/
|
||||
bool use_mobike;
|
||||
|
||||
/**
|
||||
* Use aggressive mode?
|
||||
*/
|
||||
bool aggressive;
|
||||
|
||||
/**
|
||||
* Time before starting rekeying
|
||||
*/
|
||||
|
@ -169,7 +180,7 @@ METHOD(peer_cfg_t, get_name, char*,
|
|||
return this->name;
|
||||
}
|
||||
|
||||
METHOD(peer_cfg_t, get_ike_version, u_int,
|
||||
METHOD(peer_cfg_t, get_ike_version, ike_version_t,
|
||||
private_peer_cfg_t *this)
|
||||
{
|
||||
return this->ike_version;
|
||||
|
@ -336,13 +347,13 @@ METHOD(peer_cfg_t, get_keyingtries, u_int32_t,
|
|||
}
|
||||
|
||||
METHOD(peer_cfg_t, get_rekey_time, u_int32_t,
|
||||
private_peer_cfg_t *this)
|
||||
private_peer_cfg_t *this, bool jitter)
|
||||
{
|
||||
if (this->rekey_time == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (this->jitter_time == 0)
|
||||
if (this->jitter_time == 0 || !jitter)
|
||||
{
|
||||
return this->rekey_time;
|
||||
}
|
||||
|
@ -350,13 +361,13 @@ METHOD(peer_cfg_t, get_rekey_time, u_int32_t,
|
|||
}
|
||||
|
||||
METHOD(peer_cfg_t, get_reauth_time, u_int32_t,
|
||||
private_peer_cfg_t *this)
|
||||
private_peer_cfg_t *this, bool jitter)
|
||||
{
|
||||
if (this->reauth_time == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (this->jitter_time == 0)
|
||||
if (this->jitter_time == 0 || !jitter)
|
||||
{
|
||||
return this->reauth_time;
|
||||
}
|
||||
|
@ -375,6 +386,12 @@ METHOD(peer_cfg_t, use_mobike, bool,
|
|||
return this->use_mobike;
|
||||
}
|
||||
|
||||
METHOD(peer_cfg_t, use_aggressive, bool,
|
||||
private_peer_cfg_t *this)
|
||||
{
|
||||
return this->aggressive;
|
||||
}
|
||||
|
||||
METHOD(peer_cfg_t, get_dpd, u_int32_t,
|
||||
private_peer_cfg_t *this)
|
||||
{
|
||||
|
@ -563,14 +580,14 @@ METHOD(peer_cfg_t, destroy, void,
|
|||
/*
|
||||
* Described in header-file
|
||||
*/
|
||||
peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
|
||||
cert_policy_t cert_policy, unique_policy_t unique,
|
||||
u_int32_t keyingtries, u_int32_t rekey_time,
|
||||
u_int32_t reauth_time, u_int32_t jitter_time,
|
||||
u_int32_t over_time, bool mobike, u_int32_t dpd,
|
||||
host_t *virtual_ip, char *pool,
|
||||
bool mediation, peer_cfg_t *mediated_by,
|
||||
identification_t *peer_id)
|
||||
peer_cfg_t *peer_cfg_create(char *name, ike_version_t ike_version,
|
||||
ike_cfg_t *ike_cfg, cert_policy_t cert_policy,
|
||||
unique_policy_t unique, u_int32_t keyingtries,
|
||||
u_int32_t rekey_time, u_int32_t reauth_time,
|
||||
u_int32_t jitter_time, u_int32_t over_time,
|
||||
bool mobike, bool aggressive, u_int32_t dpd,
|
||||
host_t *virtual_ip, char *pool, bool mediation,
|
||||
peer_cfg_t *mediated_by, identification_t *peer_id)
|
||||
{
|
||||
private_peer_cfg_t *this;
|
||||
|
||||
|
@ -599,6 +616,7 @@ peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
|
|||
.get_reauth_time = _get_reauth_time,
|
||||
.get_over_time = _get_over_time,
|
||||
.use_mobike = _use_mobike,
|
||||
.use_aggressive = _use_aggressive,
|
||||
.get_dpd = _get_dpd,
|
||||
.get_virtual_ip = _get_virtual_ip,
|
||||
.get_pool = _get_pool,
|
||||
|
@ -626,6 +644,7 @@ peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
|
|||
.jitter_time = jitter_time,
|
||||
.over_time = over_time,
|
||||
.use_mobike = mobike,
|
||||
.aggressive = aggressive,
|
||||
.dpd = dpd,
|
||||
.virtual_ip = virtual_ip,
|
||||
.pool = strdupnull(pool),
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#ifndef PEER_CFG_H_
|
||||
#define PEER_CFG_H_
|
||||
|
||||
typedef enum ike_version_t ike_version_t;
|
||||
typedef enum cert_policy_t cert_policy_t;
|
||||
typedef enum unique_policy_t unique_policy_t;
|
||||
typedef struct peer_cfg_t peer_cfg_t;
|
||||
|
@ -34,10 +35,25 @@ typedef struct peer_cfg_t peer_cfg_t;
|
|||
#include <config/proposal.h>
|
||||
#include <config/ike_cfg.h>
|
||||
#include <config/child_cfg.h>
|
||||
#include <sa/authenticators/authenticator.h>
|
||||
#include <sa/authenticators/eap/eap_method.h>
|
||||
#include <credentials/auth_cfg.h>
|
||||
|
||||
/**
|
||||
* IKE version.
|
||||
*/
|
||||
enum ike_version_t {
|
||||
/** any version */
|
||||
IKE_ANY = 0,
|
||||
/** IKE version 1 */
|
||||
IKEV1 = 1,
|
||||
/** IKE version 2 */
|
||||
IKEV2 = 2,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum strings fro ike_version_t
|
||||
*/
|
||||
extern enum_name_t *ike_version_names;
|
||||
|
||||
/**
|
||||
* Certificate sending policy. This is also used for certificate
|
||||
* requests when using this definition for the other peer. If
|
||||
|
@ -130,7 +146,7 @@ struct peer_cfg_t {
|
|||
*
|
||||
* @return IKE major version
|
||||
*/
|
||||
u_int (*get_ike_version)(peer_cfg_t *this);
|
||||
ike_version_t (*get_ike_version)(peer_cfg_t *this);
|
||||
|
||||
/**
|
||||
* Get the IKE config to use for initiaton.
|
||||
|
@ -211,18 +227,20 @@ struct peer_cfg_t {
|
|||
u_int32_t (*get_keyingtries) (peer_cfg_t *this);
|
||||
|
||||
/**
|
||||
* Get a time to start rekeying (is randomized with jitter).
|
||||
* Get a time to start rekeying.
|
||||
*
|
||||
* @param jitter remove a jitter value to randomize time
|
||||
* @return time in s when to start rekeying, 0 disables rekeying
|
||||
*/
|
||||
u_int32_t (*get_rekey_time)(peer_cfg_t *this);
|
||||
u_int32_t (*get_rekey_time)(peer_cfg_t *this, bool jitter);
|
||||
|
||||
/**
|
||||
* Get a time to start reauthentication (is randomized with jitter).
|
||||
* Get a time to start reauthentication.
|
||||
*
|
||||
* @param jitter remove a jitter value to randomize time
|
||||
* @return time in s when to start reauthentication, 0 disables it
|
||||
*/
|
||||
u_int32_t (*get_reauth_time)(peer_cfg_t *this);
|
||||
u_int32_t (*get_reauth_time)(peer_cfg_t *this, bool jitter);
|
||||
|
||||
/**
|
||||
* Get the timeout of a rekeying/reauthenticating SA.
|
||||
|
@ -238,6 +256,13 @@ struct peer_cfg_t {
|
|||
*/
|
||||
bool (*use_mobike) (peer_cfg_t *this);
|
||||
|
||||
/**
|
||||
* Use/Accept aggressive mode with IKEv1?.
|
||||
*
|
||||
* @return TRUE to use aggressive mode
|
||||
*/
|
||||
bool (*use_aggressive)(peer_cfg_t *this);
|
||||
|
||||
/**
|
||||
* Get the DPD check interval.
|
||||
*
|
||||
|
@ -339,6 +364,7 @@ struct peer_cfg_t {
|
|||
* @param jitter_time timerange to randomly subtract from rekey/reauth time
|
||||
* @param over_time maximum overtime before closing a rekeying/reauth SA
|
||||
* @param mobike use MOBIKE (RFC4555) if peer supports it
|
||||
* @param aggressive use/accept aggressive mode with IKEv1
|
||||
* @param dpd DPD check interval, 0 to disable
|
||||
* @param virtual_ip virtual IP for local host, or NULL
|
||||
* @param pool pool name to get configuration attributes from, or NULL
|
||||
|
@ -347,13 +373,13 @@ struct peer_cfg_t {
|
|||
* @param peer_id ID that identifies our peer at the mediation server
|
||||
* @return peer_cfg_t object
|
||||
*/
|
||||
peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
|
||||
cert_policy_t cert_policy, unique_policy_t unique,
|
||||
u_int32_t keyingtries, u_int32_t rekey_time,
|
||||
u_int32_t reauth_time, u_int32_t jitter_time,
|
||||
u_int32_t over_time, bool mobike, u_int32_t dpd,
|
||||
host_t *virtual_ip, char *pool,
|
||||
bool mediation, peer_cfg_t *mediated_by,
|
||||
identification_t *peer_id);
|
||||
peer_cfg_t *peer_cfg_create(char *name, ike_version_t ike_version,
|
||||
ike_cfg_t *ike_cfg, cert_policy_t cert_policy,
|
||||
unique_policy_t unique, u_int32_t keyingtries,
|
||||
u_int32_t rekey_time, u_int32_t reauth_time,
|
||||
u_int32_t jitter_time, u_int32_t over_time,
|
||||
bool mobike, bool aggressive, u_int32_t dpd,
|
||||
host_t *virtual_ip, char *pool, bool mediation,
|
||||
peer_cfg_t *mediated_by, identification_t *peer_id);
|
||||
|
||||
#endif /** PEER_CFG_H_ @}*/
|
||||
|
|
|
@ -217,6 +217,17 @@ METHOD(job_t, initiate_execute, void,
|
|||
|
||||
ike_sa = charon->ike_sa_manager->checkout_by_config(charon->ike_sa_manager,
|
||||
peer_cfg);
|
||||
if (!ike_sa)
|
||||
{
|
||||
listener->child_cfg->destroy(listener->child_cfg);
|
||||
peer_cfg->destroy(peer_cfg);
|
||||
/* trigger down event to release listener */
|
||||
listener->ike_sa = charon->ike_sa_manager->checkout_new(
|
||||
charon->ike_sa_manager, IKE_ANY, TRUE);
|
||||
DESTROY_IF(listener->ike_sa);
|
||||
listener->status = FAILED;
|
||||
return;
|
||||
}
|
||||
listener->ike_sa = ike_sa;
|
||||
|
||||
if (ike_sa->get_peer_cfg(ike_sa) == NULL)
|
||||
|
@ -357,7 +368,7 @@ METHOD(job_t, terminate_child_execute, void,
|
|||
|
||||
charon->bus->set_sa(charon->bus, ike_sa);
|
||||
if (ike_sa->delete_child_sa(ike_sa, child_sa->get_protocol(child_sa),
|
||||
child_sa->get_spi(child_sa, TRUE)) != DESTROY_ME)
|
||||
child_sa->get_spi(child_sa, TRUE), FALSE) != DESTROY_ME)
|
||||
{
|
||||
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
|
||||
listener->status = SUCCESS;
|
||||
|
|
|
@ -128,6 +128,7 @@ static void destroy(private_daemon_t *this)
|
|||
DESTROY_IF(this->public.ike_sa_manager);
|
||||
DESTROY_IF(this->public.controller);
|
||||
DESTROY_IF(this->public.eap);
|
||||
DESTROY_IF(this->public.xauth);
|
||||
DESTROY_IF(this->public.backends);
|
||||
DESTROY_IF(this->public.socket);
|
||||
|
||||
|
@ -272,6 +273,7 @@ private_daemon_t *daemon_create()
|
|||
charon = &this->public;
|
||||
this->public.controller = controller_create();
|
||||
this->public.eap = eap_manager_create();
|
||||
this->public.xauth = xauth_manager_create();
|
||||
this->public.backends = backend_manager_create();
|
||||
this->public.socket = socket_manager_create();
|
||||
this->public.traps = trap_manager_create();
|
||||
|
|
|
@ -148,11 +148,12 @@ typedef struct daemon_t daemon_t;
|
|||
#include <sa/trap_manager.h>
|
||||
#include <sa/shunt_manager.h>
|
||||
#include <config/backend_manager.h>
|
||||
#include <sa/authenticators/eap/eap_manager.h>
|
||||
#include <sa/eap/eap_manager.h>
|
||||
#include <sa/xauth/xauth_manager.h>
|
||||
|
||||
#ifdef ME
|
||||
#include <sa/connect_manager.h>
|
||||
#include <sa/mediation_manager.h>
|
||||
#include <sa/ikev2/connect_manager.h>
|
||||
#include <sa/ikev2/mediation_manager.h>
|
||||
#endif /* ME */
|
||||
|
||||
/**
|
||||
|
@ -235,6 +236,11 @@ struct daemon_t {
|
|||
*/
|
||||
eap_manager_t *eap;
|
||||
|
||||
/**
|
||||
* XAuth manager to maintain registered XAuth methods
|
||||
*/
|
||||
xauth_manager_t *xauth;
|
||||
|
||||
#ifdef ME
|
||||
/**
|
||||
* Connect manager
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2011 Tobias Brunner
|
||||
* Copyright (C) 2005-2009 Martin Willi
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
|
@ -108,6 +109,11 @@ struct private_generator_t {
|
|||
* to hold the length of the transform attribute in bytes.
|
||||
*/
|
||||
u_int16_t attribute_length;
|
||||
|
||||
/**
|
||||
* TRUE, if debug messages should be logged during generation.
|
||||
*/
|
||||
bool debug;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -155,8 +161,11 @@ static void make_space_available(private_generator_t *this, int bits)
|
|||
new_buffer_size = old_buffer_size + GENERATOR_DATA_BUFFER_INCREASE_VALUE;
|
||||
out_position_offset = this->out_position - this->buffer;
|
||||
|
||||
DBG2(DBG_ENC, "increasing gen buffer from %d to %d byte",
|
||||
old_buffer_size, new_buffer_size);
|
||||
if (this->debug)
|
||||
{
|
||||
DBG2(DBG_ENC, "increasing gen buffer from %d to %d byte",
|
||||
old_buffer_size, new_buffer_size);
|
||||
}
|
||||
|
||||
this->buffer = realloc(this->buffer,new_buffer_size);
|
||||
this->out_position = (this->buffer + out_position_offset);
|
||||
|
@ -205,7 +214,7 @@ static void generate_u_int_type(private_generator_t *this,
|
|||
break;
|
||||
case U_INT_16:
|
||||
case PAYLOAD_LENGTH:
|
||||
case CONFIGURATION_ATTRIBUTE_LENGTH:
|
||||
case ATTRIBUTE_LENGTH:
|
||||
number_of_bits = 16;
|
||||
break;
|
||||
case U_INT_32:
|
||||
|
@ -244,7 +253,10 @@ static void generate_u_int_type(private_generator_t *this,
|
|||
low = *(this->out_position) & 0x0F;
|
||||
/* high is set, low_val is not changed */
|
||||
*(this->out_position) = high | low;
|
||||
DBG3(DBG_ENC, " => %d", *(this->out_position));
|
||||
if (this->debug)
|
||||
{
|
||||
DBG3(DBG_ENC, " => %d", *(this->out_position));
|
||||
}
|
||||
/* write position is not changed, just bit position is moved */
|
||||
this->current_bit = 4;
|
||||
}
|
||||
|
@ -255,7 +267,10 @@ static void generate_u_int_type(private_generator_t *this,
|
|||
/* low of current byte in buffer has to be set to the new value*/
|
||||
low = *((u_int8_t *)(this->data_struct + offset)) & 0x0F;
|
||||
*(this->out_position) = high | low;
|
||||
DBG3(DBG_ENC, " => %d", *(this->out_position));
|
||||
if (this->debug)
|
||||
{
|
||||
DBG3(DBG_ENC, " => %d", *(this->out_position));
|
||||
}
|
||||
this->out_position++;
|
||||
this->current_bit = 0;
|
||||
}
|
||||
|
@ -274,7 +289,10 @@ static void generate_u_int_type(private_generator_t *this,
|
|||
{
|
||||
/* 8 bit values are written as they are */
|
||||
*this->out_position = *((u_int8_t *)(this->data_struct + offset));
|
||||
DBG3(DBG_ENC, " => %d", *(this->out_position));
|
||||
if (this->debug)
|
||||
{
|
||||
DBG3(DBG_ENC, " => %d", *(this->out_position));
|
||||
}
|
||||
this->out_position++;
|
||||
break;
|
||||
}
|
||||
|
@ -299,7 +317,10 @@ static void generate_u_int_type(private_generator_t *this,
|
|||
val |= 0x8000;
|
||||
}
|
||||
val = htons(val);
|
||||
DBG3(DBG_ENC, " => %d", val);
|
||||
if (this->debug)
|
||||
{
|
||||
DBG3(DBG_ENC, " => %d", val);
|
||||
}
|
||||
/* write bytes to buffer (set bit is overwritten) */
|
||||
write_bytes_to_buffer(this, &val, sizeof(u_int16_t));
|
||||
this->current_bit = 0;
|
||||
|
@ -308,17 +329,23 @@ static void generate_u_int_type(private_generator_t *this,
|
|||
}
|
||||
case U_INT_16:
|
||||
case PAYLOAD_LENGTH:
|
||||
case CONFIGURATION_ATTRIBUTE_LENGTH:
|
||||
case ATTRIBUTE_LENGTH:
|
||||
{
|
||||
u_int16_t val = htons(*((u_int16_t*)(this->data_struct + offset)));
|
||||
DBG3(DBG_ENC, " => %b", &val, sizeof(u_int16_t));
|
||||
if (this->debug)
|
||||
{
|
||||
DBG3(DBG_ENC, " %b", &val, sizeof(u_int16_t));
|
||||
}
|
||||
write_bytes_to_buffer(this, &val, sizeof(u_int16_t));
|
||||
break;
|
||||
}
|
||||
case U_INT_32:
|
||||
{
|
||||
u_int32_t val = htonl(*((u_int32_t*)(this->data_struct + offset)));
|
||||
DBG3(DBG_ENC, " => %b", &val, sizeof(u_int32_t));
|
||||
if (this->debug)
|
||||
{
|
||||
DBG3(DBG_ENC, " %b", &val, sizeof(u_int32_t));
|
||||
}
|
||||
write_bytes_to_buffer(this, &val, sizeof(u_int32_t));
|
||||
break;
|
||||
}
|
||||
|
@ -327,8 +354,11 @@ static void generate_u_int_type(private_generator_t *this,
|
|||
/* 64 bit are written as-is, no host order conversion */
|
||||
write_bytes_to_buffer(this, this->data_struct + offset,
|
||||
sizeof(u_int64_t));
|
||||
DBG3(DBG_ENC, " => %b", this->data_struct + offset,
|
||||
sizeof(u_int64_t));
|
||||
if (this->debug)
|
||||
{
|
||||
DBG3(DBG_ENC, " %b", this->data_struct + offset,
|
||||
sizeof(u_int64_t));
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -361,7 +391,10 @@ static void generate_flag(private_generator_t *this, u_int32_t offset)
|
|||
}
|
||||
|
||||
*(this->out_position) = *(this->out_position) | flag;
|
||||
DBG3(DBG_ENC, " => %d", *this->out_position);
|
||||
if (this->debug)
|
||||
{
|
||||
DBG3(DBG_ENC, " => %d", *this->out_position);
|
||||
}
|
||||
|
||||
this->current_bit++;
|
||||
if (this->current_bit >= 8)
|
||||
|
@ -380,12 +413,16 @@ static void generate_from_chunk(private_generator_t *this, u_int32_t offset)
|
|||
|
||||
if (this->current_bit != 0)
|
||||
{
|
||||
DBG1(DBG_ENC, "can not generate a chunk at Bitpos %d", this->current_bit);
|
||||
DBG1(DBG_ENC, "can not generate a chunk at bitpos %d",
|
||||
this->current_bit);
|
||||
return ;
|
||||
}
|
||||
|
||||
value = (chunk_t *)(this->data_struct + offset);
|
||||
DBG3(DBG_ENC, " => %B", value);
|
||||
if (this->debug)
|
||||
{
|
||||
DBG3(DBG_ENC, " %B", value);
|
||||
}
|
||||
|
||||
write_bytes_to_buffer(this, value->ptr, value->len);
|
||||
}
|
||||
|
@ -397,15 +434,17 @@ METHOD(generator_t, get_chunk, chunk_t,
|
|||
|
||||
*lenpos = (u_int32_t*)(this->buffer + this->header_length_offset);
|
||||
data = chunk_create(this->buffer, get_length(this));
|
||||
DBG3(DBG_ENC, "generated data of this generator %B", &data);
|
||||
if (this->debug)
|
||||
{
|
||||
DBG3(DBG_ENC, "generated data of this generator %B", &data);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
METHOD(generator_t, generate_payload, void,
|
||||
private_generator_t *this,payload_t *payload)
|
||||
{
|
||||
int i, offset_start;
|
||||
size_t rule_count;
|
||||
int i, offset_start, rule_count;
|
||||
encoding_rule_t *rules;
|
||||
payload_type_t payload_type;
|
||||
|
||||
|
@ -414,17 +453,23 @@ METHOD(generator_t, generate_payload, void,
|
|||
|
||||
offset_start = this->out_position - this->buffer;
|
||||
|
||||
DBG2(DBG_ENC, "generating payload of type %N",
|
||||
payload_type_names, payload_type);
|
||||
if (this->debug)
|
||||
{
|
||||
DBG2(DBG_ENC, "generating payload of type %N",
|
||||
payload_type_names, payload_type);
|
||||
}
|
||||
|
||||
/* each payload has its own encoding rules */
|
||||
payload->get_encoding_rules(payload, &rules, &rule_count);
|
||||
rule_count = payload->get_encoding_rules(payload, &rules);
|
||||
|
||||
for (i = 0; i < rule_count;i++)
|
||||
{
|
||||
DBG2(DBG_ENC, " generating rule %d %N",
|
||||
i, encoding_type_names, rules[i].type);
|
||||
switch (rules[i].type)
|
||||
if (this->debug)
|
||||
{
|
||||
DBG2(DBG_ENC, " generating rule %d %N",
|
||||
i, encoding_type_names, rules[i].type);
|
||||
}
|
||||
switch ((int)rules[i].type)
|
||||
{
|
||||
case U_INT_4:
|
||||
case U_INT_8:
|
||||
|
@ -436,7 +481,7 @@ METHOD(generator_t, generate_payload, void,
|
|||
case SPI_SIZE:
|
||||
case TS_TYPE:
|
||||
case ATTRIBUTE_TYPE:
|
||||
case CONFIGURATION_ATTRIBUTE_LENGTH:
|
||||
case ATTRIBUTE_LENGTH:
|
||||
generate_u_int_type(this, rules[i].type, rules[i].offset);
|
||||
break;
|
||||
case RESERVED_BIT:
|
||||
|
@ -449,26 +494,19 @@ METHOD(generator_t, generate_payload, void,
|
|||
break;
|
||||
case ADDRESS:
|
||||
case SPI:
|
||||
case KEY_EXCHANGE_DATA:
|
||||
case NOTIFICATION_DATA:
|
||||
case NONCE_DATA:
|
||||
case ID_DATA:
|
||||
case AUTH_DATA:
|
||||
case CERT_DATA:
|
||||
case CERTREQ_DATA:
|
||||
case SPIS:
|
||||
case CONFIGURATION_ATTRIBUTE_VALUE:
|
||||
case VID_DATA:
|
||||
case EAP_DATA:
|
||||
case CHUNK_DATA:
|
||||
case ENCRYPTED_DATA:
|
||||
case UNKNOWN_DATA:
|
||||
generate_from_chunk(this, rules[i].offset);
|
||||
break;
|
||||
case PROPOSALS:
|
||||
case TRANSFORMS:
|
||||
case TRANSFORM_ATTRIBUTES:
|
||||
case CONFIGURATION_ATTRIBUTES:
|
||||
case TRAFFIC_SELECTORS:
|
||||
case PAYLOAD_LIST + PROPOSAL_SUBSTRUCTURE:
|
||||
case PAYLOAD_LIST + PROPOSAL_SUBSTRUCTURE_V1:
|
||||
case PAYLOAD_LIST + TRANSFORM_SUBSTRUCTURE:
|
||||
case PAYLOAD_LIST + TRANSFORM_SUBSTRUCTURE_V1:
|
||||
case PAYLOAD_LIST + TRANSFORM_ATTRIBUTE:
|
||||
case PAYLOAD_LIST + TRANSFORM_ATTRIBUTE_V1:
|
||||
case PAYLOAD_LIST + CONFIGURATION_ATTRIBUTE:
|
||||
case PAYLOAD_LIST + CONFIGURATION_ATTRIBUTE_V1:
|
||||
case PAYLOAD_LIST + TRAFFIC_SELECTOR_SUBSTRUCTURE:
|
||||
{
|
||||
linked_list_t *proposals;
|
||||
enumerator_t *enumerator;
|
||||
|
@ -507,7 +545,10 @@ METHOD(generator_t, generate_payload, void,
|
|||
{
|
||||
if (!this->attribute_format)
|
||||
{
|
||||
DBG2(DBG_ENC, "attribute value has not fixed size");
|
||||
if (this->debug)
|
||||
{
|
||||
DBG2(DBG_ENC, "attribute value has not fixed size");
|
||||
}
|
||||
/* the attribute value is generated */
|
||||
generate_from_chunk(this, rules[i].offset);
|
||||
}
|
||||
|
@ -519,11 +560,14 @@ METHOD(generator_t, generate_payload, void,
|
|||
return;
|
||||
}
|
||||
}
|
||||
DBG2(DBG_ENC, "generating %N payload finished",
|
||||
payload_type_names, payload_type);
|
||||
DBG3(DBG_ENC, "generated data for this payload %b",
|
||||
this->buffer + offset_start,
|
||||
this->out_position - this->buffer - offset_start);
|
||||
if (this->debug)
|
||||
{
|
||||
DBG2(DBG_ENC, "generating %N payload finished",
|
||||
payload_type_names, payload_type);
|
||||
DBG3(DBG_ENC, "generated data for this payload %b",
|
||||
this->buffer + offset_start,
|
||||
this->out_position - this->buffer - offset_start);
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(generator_t, destroy, void,
|
||||
|
@ -547,6 +591,7 @@ generator_t *generator_create()
|
|||
.destroy = _destroy,
|
||||
},
|
||||
.buffer = malloc(GENERATOR_DATA_BUFFER_SIZE),
|
||||
.debug = TRUE,
|
||||
);
|
||||
|
||||
this->out_position = this->buffer;
|
||||
|
@ -555,3 +600,14 @@ generator_t *generator_create()
|
|||
return &this->public;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
generator_t *generator_create_no_dbg()
|
||||
{
|
||||
private_generator_t *this = (private_generator_t*)generator_create();
|
||||
|
||||
this->debug = FALSE;
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
|
|
@ -72,4 +72,12 @@ struct generator_t {
|
|||
*/
|
||||
generator_t *generator_create(void);
|
||||
|
||||
/**
|
||||
* Constructor to create a generator that does not log any debug messages > 1.
|
||||
*
|
||||
* @return generator_t object.
|
||||
*/
|
||||
generator_t *generator_create_no_dbg(void);
|
||||
|
||||
|
||||
#endif /** GENERATOR_H_ @}*/
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2006-2007 Tobias Brunner
|
||||
* Copyright (C) 2006-2011 Tobias Brunner
|
||||
* Copyright (C) 2005-2009 Martin Willi
|
||||
* Copyright (C) 2006 Daniel Roethlisberger
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
|
@ -27,15 +27,15 @@
|
|||
typedef struct message_t message_t;
|
||||
|
||||
#include <library.h>
|
||||
#include <sa/ike_sa_id.h>
|
||||
#include <network/packet.h>
|
||||
#include <encoding/payloads/ike_header.h>
|
||||
#include <encoding/payloads/notify_payload.h>
|
||||
#include <sa/keymat.h>
|
||||
#include <sa/ike_sa_id.h>
|
||||
#include <utils/linked_list.h>
|
||||
#include <crypto/aead.h>
|
||||
|
||||
/**
|
||||
* This class is used to represent an IKEv2-Message.
|
||||
* This class is used to represent an IKE-Message.
|
||||
*
|
||||
* The message handles parsing and generation of payloads
|
||||
* via parser_t/generator_t. Encryption is done transparently
|
||||
|
@ -182,7 +182,7 @@ struct message_t {
|
|||
* all payloads to encrypt are added to the encryption payload, which is
|
||||
* always the last one.
|
||||
*
|
||||
* @param payload payload to append
|
||||
* @param payload payload to append
|
||||
*/
|
||||
void (*add_payload) (message_t *this, payload_t *payload);
|
||||
|
||||
|
@ -208,14 +208,14 @@ struct message_t {
|
|||
/**
|
||||
* Parses header of message.
|
||||
*
|
||||
* Begins parisng of a message created via message_create_from_packet().
|
||||
* Begins parsing 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.
|
||||
*
|
||||
* @return
|
||||
* - SUCCESS if header could be parsed
|
||||
* - SUCCESS if header could be parsed
|
||||
* - PARSE_ERROR if corrupted/invalid data found
|
||||
* - FAILED if consistence check of header failed
|
||||
* - FAILED if consistency check of header failed
|
||||
*/
|
||||
status_t (*parse_header) (message_t *this);
|
||||
|
||||
|
@ -228,15 +228,15 @@ struct message_t {
|
|||
* If there are encrypted payloads, they get decrypted and verified using
|
||||
* the given aead transform (if given).
|
||||
*
|
||||
* @param aead aead transform to verify/decrypt message
|
||||
* @param keymat keymat to verify/decrypt message
|
||||
* @return
|
||||
* - SUCCESS if parsing successful
|
||||
* - SUCCESS if parsing successful
|
||||
* - PARSE_ERROR if message parsing failed
|
||||
* - VERIFY_ERROR if message verification failed (bad syntax)
|
||||
* - FAILED if integrity check failed
|
||||
* - INVALID_STATE if aead not supplied, but needed
|
||||
* - VERIFY_ERROR if message verification failed (bad syntax)
|
||||
* - FAILED if integrity check failed
|
||||
* - INVALID_STATE if aead not supplied, but needed
|
||||
*/
|
||||
status_t (*parse_body) (message_t *this, aead_t *aead);
|
||||
status_t (*parse_body) (message_t *this, keymat_t *keymat);
|
||||
|
||||
/**
|
||||
* Generates the UDP packet of specific message.
|
||||
|
@ -247,15 +247,15 @@ struct message_t {
|
|||
* Generation is only done once, multiple calls will just return a copy
|
||||
* of the packet.
|
||||
*
|
||||
* @param aead aead transform to encrypt/sign message
|
||||
* @param keymat keymat to encrypt/sign message
|
||||
* @param packet copy of generated packet
|
||||
* @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 aead not supplied but needed.
|
||||
* - 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 aead not supplied but needed.
|
||||
*/
|
||||
status_t (*generate) (message_t *this, aead_t *aead, packet_t **packet);
|
||||
status_t (*generate) (message_t *this, keymat_t *keymat, packet_t **packet);
|
||||
|
||||
/**
|
||||
* Check if the message has already been encoded using generate().
|
||||
|
@ -278,7 +278,7 @@ struct message_t {
|
|||
* 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.
|
||||
* message_t.destroy or next call of message_t.set_source.
|
||||
*
|
||||
* @param host host_t object representing source host
|
||||
*/
|
||||
|
@ -298,7 +298,7 @@ struct message_t {
|
|||
* 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.
|
||||
* message_t.destroy or next call of message_t.set_destination.
|
||||
*
|
||||
* @param host host_t object representing destination host
|
||||
*/
|
||||
|
@ -344,9 +344,9 @@ struct message_t {
|
|||
packet_t * (*get_packet) (message_t *this);
|
||||
|
||||
/**
|
||||
* Returns a clone of the internal stored packet_t data.
|
||||
* Returns a chunk pointing to internal packet_t data.
|
||||
*
|
||||
* @return clone of the internal stored packet_t data.
|
||||
* @return packet data.
|
||||
*/
|
||||
chunk_t (*get_packet_data) (message_t *this);
|
||||
|
||||
|
@ -357,26 +357,27 @@ struct message_t {
|
|||
};
|
||||
|
||||
/**
|
||||
* Creates an message_t object from a incoming UDP Packet.
|
||||
* Creates a message_t object from an incoming UDP packet.
|
||||
*
|
||||
* The given packet gets owned by the message. The message is uninitialized,
|
||||
* call parse_header() to populate header fields.
|
||||
*
|
||||
* @param packet packet_t object which is assigned to message
|
||||
* @return message_t object
|
||||
* @return message_t object
|
||||
*/
|
||||
message_t * message_create_from_packet(packet_t *packet);
|
||||
|
||||
message_t *message_create_from_packet(packet_t *packet);
|
||||
|
||||
/**
|
||||
* Creates an empty message_t object.
|
||||
* Creates an empty message_t object for a specific major/minor version.
|
||||
*
|
||||
* - exchange_type is set to NOT_SET
|
||||
* - original_initiator is set to TRUE
|
||||
* - is_request is set to TRUE
|
||||
*
|
||||
* @return message_t object
|
||||
* @param major major IKE version of this message
|
||||
* @param minor minor IKE version of this message
|
||||
* @return message_t object
|
||||
*/
|
||||
message_t * message_create(void);
|
||||
message_t *message_create(int major, int minor);
|
||||
|
||||
#endif /** MESSAGE_H_ @}*/
|
||||
|
|
|
@ -137,7 +137,7 @@ static bool parse_uint4(private_parser_t *this, int rule_number,
|
|||
}
|
||||
if (output_pos)
|
||||
{
|
||||
DBG3(DBG_ENC, " => %d", *output_pos);
|
||||
DBG3(DBG_ENC, " => %hhu", *output_pos);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -159,7 +159,7 @@ static bool parse_uint8(private_parser_t *this, int rule_number,
|
|||
if (output_pos)
|
||||
{
|
||||
*output_pos = *(this->byte_pos);
|
||||
DBG3(DBG_ENC, " => %d", *output_pos);
|
||||
DBG3(DBG_ENC, " => %hhu", *output_pos);
|
||||
}
|
||||
this->byte_pos++;
|
||||
return TRUE;
|
||||
|
@ -183,7 +183,7 @@ static bool parse_uint15(private_parser_t *this, int rule_number,
|
|||
{
|
||||
memcpy(output_pos, this->byte_pos, sizeof(u_int16_t));
|
||||
*output_pos = ntohs(*output_pos) & ~0x8000;
|
||||
DBG3(DBG_ENC, " => %d", *output_pos);
|
||||
DBG3(DBG_ENC, " => %hu", *output_pos);
|
||||
}
|
||||
this->byte_pos += sizeof(u_int16_t);
|
||||
this->bit_pos = 0;
|
||||
|
@ -208,7 +208,7 @@ static bool parse_uint16(private_parser_t *this, int rule_number,
|
|||
{
|
||||
memcpy(output_pos, this->byte_pos, sizeof(u_int16_t));
|
||||
*output_pos = ntohs(*output_pos);
|
||||
DBG3(DBG_ENC, " => %d", *output_pos);
|
||||
DBG3(DBG_ENC, " => %hu", *output_pos);
|
||||
}
|
||||
this->byte_pos += sizeof(u_int16_t);
|
||||
return TRUE;
|
||||
|
@ -231,7 +231,7 @@ static bool parse_uint32(private_parser_t *this, int rule_number,
|
|||
{
|
||||
memcpy(output_pos, this->byte_pos, sizeof(u_int32_t));
|
||||
*output_pos = ntohl(*output_pos);
|
||||
DBG3(DBG_ENC, " => %d", *output_pos);
|
||||
DBG3(DBG_ENC, " => %u", *output_pos);
|
||||
}
|
||||
this->byte_pos += sizeof(u_int32_t);
|
||||
return TRUE;
|
||||
|
@ -254,7 +254,7 @@ static bool parse_bytes(private_parser_t *this, int rule_number,
|
|||
if (output_pos)
|
||||
{
|
||||
memcpy(output_pos, this->byte_pos, bytes);
|
||||
DBG3(DBG_ENC, " => %b", output_pos, bytes);
|
||||
DBG3(DBG_ENC, " %b", output_pos, bytes);
|
||||
}
|
||||
this->byte_pos += bytes;
|
||||
return TRUE;
|
||||
|
@ -352,7 +352,7 @@ static bool parse_chunk(private_parser_t *this, int rule_number,
|
|||
{
|
||||
*output_pos = chunk_alloc(length);
|
||||
memcpy(output_pos->ptr, this->byte_pos, length);
|
||||
DBG3(DBG_ENC, " => %b", output_pos->ptr, length);
|
||||
DBG3(DBG_ENC, " %b", output_pos->ptr, length);
|
||||
}
|
||||
this->byte_pos += length;
|
||||
return TRUE;
|
||||
|
@ -363,11 +363,10 @@ METHOD(parser_t, parse_payload, status_t,
|
|||
{
|
||||
payload_t *pld;
|
||||
void *output;
|
||||
size_t rule_count;
|
||||
int payload_length = 0, spi_size = 0, attribute_length = 0;
|
||||
int payload_length = 0, spi_size = 0, attribute_length = 0, header_length;
|
||||
u_int16_t ts_type = 0;
|
||||
bool attribute_format = FALSE;
|
||||
int rule_number;
|
||||
int rule_number, rule_count;
|
||||
encoding_rule_t *rule;
|
||||
|
||||
/* create instance of the payload to parse */
|
||||
|
@ -381,15 +380,17 @@ METHOD(parser_t, parse_payload, status_t,
|
|||
|
||||
/* base pointer for output, avoids casting in every rule */
|
||||
output = pld;
|
||||
|
||||
/* parse the payload with its own rulse */
|
||||
pld->get_encoding_rules(pld, &this->rules, &rule_count);
|
||||
rule_count = pld->get_encoding_rules(pld, &this->rules);
|
||||
for (rule_number = 0; rule_number < rule_count; rule_number++)
|
||||
{
|
||||
/* update header length for each rule, as it is dynamic (SPIs) */
|
||||
header_length = pld->get_header_length(pld);
|
||||
|
||||
rule = &(this->rules[rule_number]);
|
||||
DBG2(DBG_ENC, " parsing rule %d %N",
|
||||
rule_number, encoding_type_names, rule->type);
|
||||
switch (rule->type)
|
||||
switch ((int)rule->type)
|
||||
{
|
||||
case U_INT_4:
|
||||
{
|
||||
|
@ -457,7 +458,8 @@ METHOD(parser_t, parse_payload, status_t,
|
|||
}
|
||||
/* parsed u_int16 should be aligned */
|
||||
payload_length = *(u_int16_t*)(output + rule->offset);
|
||||
if (payload_length < UNKNOWN_PAYLOAD_HEADER_LENGTH)
|
||||
/* all payloads must have at least 4 bytes header */
|
||||
if (payload_length < 4)
|
||||
{
|
||||
pld->destroy(pld);
|
||||
return PARSE_ERROR;
|
||||
|
@ -484,49 +486,41 @@ METHOD(parser_t, parse_payload, status_t,
|
|||
}
|
||||
break;
|
||||
}
|
||||
case PROPOSALS:
|
||||
case PAYLOAD_LIST + PROPOSAL_SUBSTRUCTURE:
|
||||
case PAYLOAD_LIST + PROPOSAL_SUBSTRUCTURE_V1:
|
||||
case PAYLOAD_LIST + TRANSFORM_SUBSTRUCTURE:
|
||||
case PAYLOAD_LIST + TRANSFORM_SUBSTRUCTURE_V1:
|
||||
case PAYLOAD_LIST + TRANSFORM_ATTRIBUTE:
|
||||
case PAYLOAD_LIST + TRANSFORM_ATTRIBUTE_V1:
|
||||
case PAYLOAD_LIST + CONFIGURATION_ATTRIBUTE:
|
||||
case PAYLOAD_LIST + CONFIGURATION_ATTRIBUTE_V1:
|
||||
case PAYLOAD_LIST + TRAFFIC_SELECTOR_SUBSTRUCTURE:
|
||||
{
|
||||
if (payload_length < SA_PAYLOAD_HEADER_LENGTH ||
|
||||
if (payload_length < header_length ||
|
||||
!parse_list(this, rule_number, output + rule->offset,
|
||||
PROPOSAL_SUBSTRUCTURE,
|
||||
payload_length - SA_PAYLOAD_HEADER_LENGTH))
|
||||
rule->type - PAYLOAD_LIST,
|
||||
payload_length - header_length))
|
||||
{
|
||||
pld->destroy(pld);
|
||||
return PARSE_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TRANSFORMS:
|
||||
case CHUNK_DATA:
|
||||
{
|
||||
if (payload_length <
|
||||
spi_size + PROPOSAL_SUBSTRUCTURE_HEADER_LENGTH ||
|
||||
!parse_list(this, rule_number, output + rule->offset,
|
||||
TRANSFORM_SUBSTRUCTURE, payload_length - spi_size -
|
||||
PROPOSAL_SUBSTRUCTURE_HEADER_LENGTH))
|
||||
if (payload_length < header_length ||
|
||||
!parse_chunk(this, rule_number, output + rule->offset,
|
||||
payload_length - header_length))
|
||||
{
|
||||
pld->destroy(pld);
|
||||
return PARSE_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TRANSFORM_ATTRIBUTES:
|
||||
case ENCRYPTED_DATA:
|
||||
{
|
||||
if (payload_length < TRANSFORM_SUBSTRUCTURE_HEADER_LENGTH ||
|
||||
!parse_list(this, rule_number, output + rule->offset,
|
||||
TRANSFORM_ATTRIBUTE,
|
||||
payload_length - TRANSFORM_SUBSTRUCTURE_HEADER_LENGTH))
|
||||
{
|
||||
pld->destroy(pld);
|
||||
return PARSE_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CONFIGURATION_ATTRIBUTES:
|
||||
{
|
||||
if (payload_length < CP_PAYLOAD_HEADER_LENGTH ||
|
||||
!parse_list(this, rule_number, output + rule->offset,
|
||||
CONFIGURATION_ATTRIBUTE,
|
||||
payload_length - CP_PAYLOAD_HEADER_LENGTH))
|
||||
if (!parse_chunk(this, rule_number, output + rule->offset,
|
||||
this->input_roof - this->byte_pos))
|
||||
{
|
||||
pld->destroy(pld);
|
||||
return PARSE_ERROR;
|
||||
|
@ -552,7 +546,7 @@ METHOD(parser_t, parse_payload, status_t,
|
|||
}
|
||||
break;
|
||||
}
|
||||
case CONFIGURATION_ATTRIBUTE_LENGTH:
|
||||
case ATTRIBUTE_LENGTH:
|
||||
{
|
||||
if (!parse_uint16(this, rule_number, output + rule->offset))
|
||||
{
|
||||
|
@ -583,137 +577,6 @@ METHOD(parser_t, parse_payload, status_t,
|
|||
}
|
||||
break;
|
||||
}
|
||||
case NONCE_DATA:
|
||||
{
|
||||
if (payload_length < NONCE_PAYLOAD_HEADER_LENGTH ||
|
||||
!parse_chunk(this, rule_number, output + rule->offset,
|
||||
payload_length - NONCE_PAYLOAD_HEADER_LENGTH))
|
||||
{
|
||||
pld->destroy(pld);
|
||||
return PARSE_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ID_DATA:
|
||||
{
|
||||
if (payload_length < ID_PAYLOAD_HEADER_LENGTH ||
|
||||
!parse_chunk(this, rule_number, output + rule->offset,
|
||||
payload_length - ID_PAYLOAD_HEADER_LENGTH))
|
||||
{
|
||||
pld->destroy(pld);
|
||||
return PARSE_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AUTH_DATA:
|
||||
{
|
||||
if (payload_length < AUTH_PAYLOAD_HEADER_LENGTH ||
|
||||
!parse_chunk(this, rule_number, output + rule->offset,
|
||||
payload_length - AUTH_PAYLOAD_HEADER_LENGTH))
|
||||
{
|
||||
pld->destroy(pld);
|
||||
return PARSE_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CERT_DATA:
|
||||
{
|
||||
if (payload_length < CERT_PAYLOAD_HEADER_LENGTH ||
|
||||
!parse_chunk(this, rule_number, output + rule->offset,
|
||||
payload_length - CERT_PAYLOAD_HEADER_LENGTH))
|
||||
{
|
||||
pld->destroy(pld);
|
||||
return PARSE_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CERTREQ_DATA:
|
||||
{
|
||||
if (payload_length < CERTREQ_PAYLOAD_HEADER_LENGTH ||
|
||||
!parse_chunk(this, rule_number, output + rule->offset,
|
||||
payload_length - CERTREQ_PAYLOAD_HEADER_LENGTH))
|
||||
{
|
||||
pld->destroy(pld);
|
||||
return PARSE_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EAP_DATA:
|
||||
{
|
||||
if (payload_length < EAP_PAYLOAD_HEADER_LENGTH ||
|
||||
!parse_chunk(this, rule_number, output + rule->offset,
|
||||
payload_length - EAP_PAYLOAD_HEADER_LENGTH))
|
||||
{
|
||||
pld->destroy(pld);
|
||||
return PARSE_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SPIS:
|
||||
{
|
||||
if (payload_length < DELETE_PAYLOAD_HEADER_LENGTH ||
|
||||
!parse_chunk(this, rule_number, output + rule->offset,
|
||||
payload_length - DELETE_PAYLOAD_HEADER_LENGTH))
|
||||
{
|
||||
pld->destroy(pld);
|
||||
return PARSE_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VID_DATA:
|
||||
{
|
||||
if (payload_length < VENDOR_ID_PAYLOAD_HEADER_LENGTH ||
|
||||
!parse_chunk(this, rule_number, output + rule->offset,
|
||||
payload_length - VENDOR_ID_PAYLOAD_HEADER_LENGTH))
|
||||
{
|
||||
pld->destroy(pld);
|
||||
return PARSE_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CONFIGURATION_ATTRIBUTE_VALUE:
|
||||
{
|
||||
if (!parse_chunk(this, rule_number, output + rule->offset,
|
||||
attribute_length))
|
||||
{
|
||||
pld->destroy(pld);
|
||||
return PARSE_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case KEY_EXCHANGE_DATA:
|
||||
{
|
||||
if (payload_length < KE_PAYLOAD_HEADER_LENGTH ||
|
||||
!parse_chunk(this, rule_number, output + rule->offset,
|
||||
payload_length - KE_PAYLOAD_HEADER_LENGTH))
|
||||
{
|
||||
pld->destroy(pld);
|
||||
return PARSE_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NOTIFICATION_DATA:
|
||||
{
|
||||
if (payload_length < NOTIFY_PAYLOAD_HEADER_LENGTH + spi_size ||
|
||||
!parse_chunk(this, rule_number, output + rule->offset,
|
||||
payload_length - NOTIFY_PAYLOAD_HEADER_LENGTH - spi_size))
|
||||
{
|
||||
pld->destroy(pld);
|
||||
return PARSE_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ENCRYPTED_DATA:
|
||||
{
|
||||
if (payload_length < ENCRYPTION_PAYLOAD_HEADER_LENGTH ||
|
||||
!parse_chunk(this, rule_number, output + rule->offset,
|
||||
payload_length - ENCRYPTION_PAYLOAD_HEADER_LENGTH))
|
||||
{
|
||||
pld->destroy(pld);
|
||||
return PARSE_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TS_TYPE:
|
||||
{
|
||||
if (!parse_uint8(this, rule_number, output + rule->offset))
|
||||
|
@ -736,29 +599,6 @@ METHOD(parser_t, parse_payload, status_t,
|
|||
}
|
||||
break;
|
||||
}
|
||||
case TRAFFIC_SELECTORS:
|
||||
{
|
||||
if (payload_length < TS_PAYLOAD_HEADER_LENGTH ||
|
||||
!parse_list(this, rule_number, output + rule->offset,
|
||||
TRAFFIC_SELECTOR_SUBSTRUCTURE,
|
||||
payload_length - TS_PAYLOAD_HEADER_LENGTH))
|
||||
{
|
||||
pld->destroy(pld);
|
||||
return PARSE_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case UNKNOWN_DATA:
|
||||
{
|
||||
if (payload_length < UNKNOWN_PAYLOAD_HEADER_LENGTH ||
|
||||
!parse_chunk(this, rule_number, output + rule->offset,
|
||||
payload_length - UNKNOWN_PAYLOAD_HEADER_LENGTH))
|
||||
{
|
||||
pld->destroy(pld);
|
||||
return PARSE_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
DBG1(DBG_ENC, " no rule to parse rule %d %N",
|
||||
|
|
|
@ -74,7 +74,7 @@ struct private_auth_payload_t {
|
|||
* The defined offsets are the positions in a object of type
|
||||
* private_auth_payload_t.
|
||||
*/
|
||||
encoding_rule_t auth_payload_encodings[] = {
|
||||
static encoding_rule_t 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 */
|
||||
|
@ -96,7 +96,7 @@ encoding_rule_t auth_payload_encodings[] = {
|
|||
{ RESERVED_BYTE, offsetof(private_auth_payload_t, reserved_byte[1]) },
|
||||
{ RESERVED_BYTE, offsetof(private_auth_payload_t, reserved_byte[2]) },
|
||||
/* some auth data bytes, length is defined in PAYLOAD_LENGTH */
|
||||
{ AUTH_DATA, offsetof(private_auth_payload_t, auth_data) }
|
||||
{ CHUNK_DATA, offsetof(private_auth_payload_t, auth_data) }
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -119,11 +119,17 @@ METHOD(payload_t, verify, status_t,
|
|||
return SUCCESS;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_encoding_rules, void,
|
||||
private_auth_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
|
||||
METHOD(payload_t, get_encoding_rules, int,
|
||||
private_auth_payload_t *this, encoding_rule_t **rules)
|
||||
{
|
||||
*rules = auth_payload_encodings;
|
||||
*rule_count = countof(auth_payload_encodings);
|
||||
*rules = encodings;
|
||||
return countof(encodings);
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_header_length, int,
|
||||
private_auth_payload_t *this)
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_type, payload_type_t,
|
||||
|
@ -167,7 +173,7 @@ METHOD(auth_payload_t, set_data, void,
|
|||
{
|
||||
free(this->auth_data.ptr);
|
||||
this->auth_data = chunk_clone(data);
|
||||
this->payload_length = AUTH_PAYLOAD_HEADER_LENGTH + this->auth_data.len;
|
||||
this->payload_length = get_header_length(this) + this->auth_data.len;
|
||||
}
|
||||
|
||||
METHOD(auth_payload_t, get_data, chunk_t,
|
||||
|
@ -195,6 +201,7 @@ auth_payload_t *auth_payload_create()
|
|||
.payload_interface = {
|
||||
.verify = _verify,
|
||||
.get_encoding_rules = _get_encoding_rules,
|
||||
.get_header_length = _get_header_length,
|
||||
.get_length = _get_length,
|
||||
.get_next_type = _get_next_type,
|
||||
.set_next_type = _set_next_type,
|
||||
|
@ -208,7 +215,7 @@ auth_payload_t *auth_payload_create()
|
|||
.destroy = _destroy,
|
||||
},
|
||||
.next_payload = NO_PAYLOAD,
|
||||
.payload_length = AUTH_PAYLOAD_HEADER_LENGTH,
|
||||
.payload_length = get_header_length(this),
|
||||
);
|
||||
return &this->public;
|
||||
}
|
||||
|
|
|
@ -26,12 +26,7 @@ typedef struct auth_payload_t auth_payload_t;
|
|||
|
||||
#include <library.h>
|
||||
#include <encoding/payloads/payload.h>
|
||||
#include <sa/authenticators/authenticator.h>
|
||||
|
||||
/**
|
||||
* Length of a auth payload without the auth data in bytes.
|
||||
*/
|
||||
#define AUTH_PAYLOAD_HEADER_LENGTH 8
|
||||
#include <sa/authenticator.h>
|
||||
|
||||
/**
|
||||
* Class representing an IKEv2 AUTH payload.
|
||||
|
|
|
@ -86,6 +86,11 @@ struct private_cert_payload_t {
|
|||
* TRUE if the "Hash and URL" data is invalid
|
||||
*/
|
||||
bool invalid_hash_and_url;
|
||||
|
||||
/**
|
||||
* The payload type.
|
||||
*/
|
||||
payload_type_t type;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -95,7 +100,7 @@ struct private_cert_payload_t {
|
|||
* private_cert_payload_t.
|
||||
*
|
||||
*/
|
||||
encoding_rule_t cert_payload_encodings[] = {
|
||||
static encoding_rule_t 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 */
|
||||
|
@ -113,7 +118,7 @@ encoding_rule_t cert_payload_encodings[] = {
|
|||
/* 1 Byte CERT type*/
|
||||
{ U_INT_8, offsetof(private_cert_payload_t, encoding) },
|
||||
/* some cert data bytes, length is defined in PAYLOAD_LENGTH */
|
||||
{ CERT_DATA, offsetof(private_cert_payload_t, data) }
|
||||
{ CHUNK_DATA, offsetof(private_cert_payload_t, data) }
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -166,17 +171,23 @@ METHOD(payload_t, verify, status_t,
|
|||
return SUCCESS;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_encoding_rules, void,
|
||||
private_cert_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
|
||||
METHOD(payload_t, get_encoding_rules, int,
|
||||
private_cert_payload_t *this, encoding_rule_t **rules)
|
||||
{
|
||||
*rules = cert_payload_encodings;
|
||||
*rule_count = countof(cert_payload_encodings);
|
||||
*rules = encodings;
|
||||
return countof(encodings);
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_header_length, int,
|
||||
private_cert_payload_t *this)
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_type, payload_type_t,
|
||||
private_cert_payload_t *this)
|
||||
{
|
||||
return CERTIFICATE;
|
||||
return this->type;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_next_type, payload_type_t,
|
||||
|
@ -261,7 +272,7 @@ METHOD2(payload_t, cert_payload_t, destroy, void,
|
|||
/*
|
||||
* Described in header
|
||||
*/
|
||||
cert_payload_t *cert_payload_create()
|
||||
cert_payload_t *cert_payload_create(payload_type_t type)
|
||||
{
|
||||
private_cert_payload_t *this;
|
||||
|
||||
|
@ -270,6 +281,7 @@ cert_payload_t *cert_payload_create()
|
|||
.payload_interface = {
|
||||
.verify = _verify,
|
||||
.get_encoding_rules = _get_encoding_rules,
|
||||
.get_header_length = _get_header_length,
|
||||
.get_length = _get_length,
|
||||
.get_next_type = _get_next_type,
|
||||
.set_next_type = _set_next_type,
|
||||
|
@ -283,7 +295,8 @@ cert_payload_t *cert_payload_create()
|
|||
.destroy = _destroy,
|
||||
},
|
||||
.next_payload = NO_PAYLOAD,
|
||||
.payload_length = CERT_PAYLOAD_HEADER_LENGTH,
|
||||
.payload_length = get_header_length(this),
|
||||
.type = type,
|
||||
);
|
||||
return &this->public;
|
||||
}
|
||||
|
@ -291,10 +304,12 @@ cert_payload_t *cert_payload_create()
|
|||
/*
|
||||
* Described in header
|
||||
*/
|
||||
cert_payload_t *cert_payload_create_from_cert(certificate_t *cert)
|
||||
cert_payload_t *cert_payload_create_from_cert(payload_type_t type,
|
||||
certificate_t *cert)
|
||||
{
|
||||
private_cert_payload_t *this = (private_cert_payload_t*)cert_payload_create();
|
||||
private_cert_payload_t *this;
|
||||
|
||||
this = (private_cert_payload_t*)cert_payload_create(type);
|
||||
switch (cert->get_type(cert))
|
||||
{
|
||||
case CERT_X509:
|
||||
|
@ -312,7 +327,8 @@ cert_payload_t *cert_payload_create_from_cert(certificate_t *cert)
|
|||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
this->payload_length = CERT_PAYLOAD_HEADER_LENGTH + this->data.len;
|
||||
this->payload_length = get_header_length(this) + this->data.len;
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
|
@ -321,23 +337,29 @@ cert_payload_t *cert_payload_create_from_cert(certificate_t *cert)
|
|||
*/
|
||||
cert_payload_t *cert_payload_create_from_hash_and_url(chunk_t hash, char *url)
|
||||
{
|
||||
private_cert_payload_t *this = (private_cert_payload_t*)cert_payload_create();
|
||||
private_cert_payload_t *this;
|
||||
|
||||
this = (private_cert_payload_t*)cert_payload_create(CERTIFICATE);
|
||||
this->encoding = ENC_X509_HASH_AND_URL;
|
||||
this->data = chunk_cat("cc", hash, chunk_create(url, strlen(url)));
|
||||
this->payload_length = CERT_PAYLOAD_HEADER_LENGTH + this->data.len;
|
||||
this->payload_length = get_header_length(this) + this->data.len;
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
cert_payload_t *cert_payload_create_custom(cert_encoding_t type, chunk_t data)
|
||||
cert_payload_t *cert_payload_create_custom(payload_type_t type,
|
||||
cert_encoding_t encoding, chunk_t data)
|
||||
{
|
||||
private_cert_payload_t *this = (private_cert_payload_t*)cert_payload_create();
|
||||
private_cert_payload_t *this;
|
||||
|
||||
this->encoding = type;
|
||||
this = (private_cert_payload_t*)cert_payload_create(type);
|
||||
this->encoding = encoding;
|
||||
this->data = data;
|
||||
this->payload_length = CERT_PAYLOAD_HEADER_LENGTH + this->data.len;
|
||||
this->payload_length = get_header_length(this) + this->data.len;
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,11 +30,6 @@ typedef enum cert_encoding_t cert_encoding_t;
|
|||
#include <credentials/certificates/certificate.h>
|
||||
#include <encoding/payloads/payload.h>
|
||||
|
||||
/**
|
||||
* Length of a cert payload without the cert data in bytes.
|
||||
*/
|
||||
#define CERT_PAYLOAD_HEADER_LENGTH 5
|
||||
|
||||
/**
|
||||
* Certifcate encodings, as in RFC4306
|
||||
*/
|
||||
|
@ -60,9 +55,7 @@ enum cert_encoding_t {
|
|||
extern enum_name_t *cert_encoding_names;
|
||||
|
||||
/**
|
||||
* Class representing an IKEv2 CERT payload.
|
||||
*
|
||||
* The CERT payload format is described in RFC section 3.6.
|
||||
* Class representing an IKEv1/IKEv2 CERT payload.
|
||||
*/
|
||||
struct cert_payload_t {
|
||||
|
||||
|
@ -103,7 +96,6 @@ struct cert_payload_t {
|
|||
*/
|
||||
char *(*get_url)(cert_payload_t *this);
|
||||
|
||||
|
||||
/**
|
||||
* Destroys the cert_payload object.
|
||||
*/
|
||||
|
@ -113,23 +105,26 @@ struct cert_payload_t {
|
|||
/**
|
||||
* Creates an empty certificate payload.
|
||||
*
|
||||
* @param type payload type (for IKEv1 or IKEv2)
|
||||
* @return cert_payload_t object
|
||||
*/
|
||||
cert_payload_t *cert_payload_create(void);
|
||||
cert_payload_t *cert_payload_create(payload_type_t type);
|
||||
|
||||
/**
|
||||
* Creates a certificate payload with an embedded certificate.
|
||||
*
|
||||
* @param type payload type (for IKEv1 or IKEv2)
|
||||
* @param cert certificate to embed
|
||||
* @return cert_payload_t object
|
||||
*/
|
||||
cert_payload_t *cert_payload_create_from_cert(certificate_t *cert);
|
||||
cert_payload_t *cert_payload_create_from_cert(payload_type_t type,
|
||||
certificate_t *cert);
|
||||
|
||||
/**
|
||||
* Creates a certificate payload with hash and URL encoding of a certificate.
|
||||
* Creates an IKEv2 certificate payload with hash and URL encoding.
|
||||
*
|
||||
* @param hash hash of the DER encoded certificate (get's cloned)
|
||||
* @param url the URL to locate the certificate (get's cloned)
|
||||
* @param url URL to the certificate
|
||||
* @return cert_payload_t object
|
||||
*/
|
||||
cert_payload_t *cert_payload_create_from_hash_and_url(chunk_t hash, char *url);
|
||||
|
@ -137,10 +132,12 @@ cert_payload_t *cert_payload_create_from_hash_and_url(chunk_t hash, char *url);
|
|||
/**
|
||||
* Creates a custom certificate payload using type and associated data.
|
||||
*
|
||||
* @param type encoding type of certificate
|
||||
* @param type payload type (for IKEv1 or IKEv2)
|
||||
* @param encoding encoding type of certificate
|
||||
* @param data associated data (gets owned)
|
||||
* @return cert_payload_t object
|
||||
*/
|
||||
cert_payload_t *cert_payload_create_custom(cert_encoding_t type, chunk_t data);
|
||||
cert_payload_t *cert_payload_create_custom(payload_type_t type,
|
||||
cert_encoding_t encoding, chunk_t data);
|
||||
|
||||
#endif /** CERT_PAYLOAD_H_ @}*/
|
||||
|
|
|
@ -64,15 +64,17 @@ struct private_certreq_payload_t {
|
|||
* The contained certreq data value.
|
||||
*/
|
||||
chunk_t data;
|
||||
|
||||
/**
|
||||
* Payload type CERTIFICATE_REQUEST or CERTIFICATE_REQUEST_V1
|
||||
*/
|
||||
payload_type_t type;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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 rules for CERTREQ payload.
|
||||
*/
|
||||
encoding_rule_t certreq_payload_encodings[] = {
|
||||
static encoding_rule_t 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 */
|
||||
|
@ -90,7 +92,7 @@ encoding_rule_t certreq_payload_encodings[] = {
|
|||
/* 1 Byte CERTREQ type*/
|
||||
{ U_INT_8, offsetof(private_certreq_payload_t, encoding) },
|
||||
/* some certreq data bytes, length is defined in PAYLOAD_LENGTH */
|
||||
{ CERTREQ_DATA, offsetof(private_certreq_payload_t, data) }
|
||||
{ CHUNK_DATA, offsetof(private_certreq_payload_t, data) }
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -109,7 +111,8 @@ encoding_rule_t certreq_payload_encodings[] = {
|
|||
METHOD(payload_t, verify, status_t,
|
||||
private_certreq_payload_t *this)
|
||||
{
|
||||
if (this->encoding == ENC_X509_SIGNATURE)
|
||||
if (this->type == CERTIFICATE_REQUEST &&
|
||||
this->encoding == ENC_X509_SIGNATURE)
|
||||
{
|
||||
if (this->data.len < HASH_SIZE_SHA1 ||
|
||||
this->data.len % HASH_SIZE_SHA1)
|
||||
|
@ -122,17 +125,23 @@ METHOD(payload_t, verify, status_t,
|
|||
return SUCCESS;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_encoding_rules, void,
|
||||
private_certreq_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
|
||||
METHOD(payload_t, get_encoding_rules, int,
|
||||
private_certreq_payload_t *this, encoding_rule_t **rules)
|
||||
{
|
||||
*rules = certreq_payload_encodings;
|
||||
*rule_count = countof(certreq_payload_encodings);
|
||||
*rules = encodings;
|
||||
return countof(encodings);
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_header_length, int,
|
||||
private_certreq_payload_t *this)
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_type, payload_type_t,
|
||||
private_certreq_payload_t *this)
|
||||
{
|
||||
return CERTIFICATE_REQUEST;
|
||||
return this->type;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_next_type, payload_type_t,
|
||||
|
@ -153,6 +162,16 @@ METHOD(payload_t, get_length, size_t,
|
|||
return this->payload_length;
|
||||
}
|
||||
|
||||
METHOD(certreq_payload_t, get_dn, identification_t*,
|
||||
private_certreq_payload_t *this)
|
||||
{
|
||||
if (this->data.len)
|
||||
{
|
||||
return identification_create_from_encoding(ID_DER_ASN1_DN, this->data);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
METHOD(certreq_payload_t, add_keyid, void,
|
||||
private_certreq_payload_t *this, chunk_t keyid)
|
||||
{
|
||||
|
@ -200,6 +219,10 @@ METHOD(certreq_payload_t, create_keyid_enumerator, enumerator_t*,
|
|||
{
|
||||
keyid_enumerator_t *enumerator;
|
||||
|
||||
if (this->type == CERTIFICATE_REQUEST_V1)
|
||||
{
|
||||
return enumerator_create_empty();
|
||||
}
|
||||
INIT(enumerator,
|
||||
.public = {
|
||||
.enumerate = (void*)_keyid_enumerate,
|
||||
|
@ -232,7 +255,7 @@ METHOD2(payload_t, certreq_payload_t, destroy, void,
|
|||
/*
|
||||
* Described in header
|
||||
*/
|
||||
certreq_payload_t *certreq_payload_create()
|
||||
certreq_payload_t *certreq_payload_create(payload_type_t type)
|
||||
{
|
||||
private_certreq_payload_t *this;
|
||||
|
||||
|
@ -241,6 +264,7 @@ certreq_payload_t *certreq_payload_create()
|
|||
.payload_interface = {
|
||||
.verify = _verify,
|
||||
.get_encoding_rules = _get_encoding_rules,
|
||||
.get_header_length = _get_header_length,
|
||||
.get_length = _get_length,
|
||||
.get_next_type = _get_next_type,
|
||||
.set_next_type = _set_next_type,
|
||||
|
@ -251,9 +275,11 @@ certreq_payload_t *certreq_payload_create()
|
|||
.get_cert_type = _get_cert_type,
|
||||
.add_keyid = _add_keyid,
|
||||
.destroy = _destroy,
|
||||
.get_dn = _get_dn,
|
||||
},
|
||||
.next_payload = NO_PAYLOAD,
|
||||
.payload_length = CERTREQ_PAYLOAD_HEADER_LENGTH,
|
||||
.payload_length = get_header_length(this),
|
||||
.type = type,
|
||||
);
|
||||
return &this->public;
|
||||
}
|
||||
|
@ -263,8 +289,10 @@ certreq_payload_t *certreq_payload_create()
|
|||
*/
|
||||
certreq_payload_t *certreq_payload_create_type(certificate_type_t type)
|
||||
{
|
||||
private_certreq_payload_t *this = (private_certreq_payload_t*)certreq_payload_create();
|
||||
private_certreq_payload_t *this;
|
||||
|
||||
this = (private_certreq_payload_t*)
|
||||
certreq_payload_create(CERTIFICATE_REQUEST);
|
||||
switch (type)
|
||||
{
|
||||
case CERT_X509:
|
||||
|
@ -279,3 +307,19 @@ certreq_payload_t *certreq_payload_create_type(certificate_type_t type)
|
|||
return &this->public;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
certreq_payload_t *certreq_payload_create_dn(identification_t *id)
|
||||
{
|
||||
private_certreq_payload_t *this;
|
||||
|
||||
this = (private_certreq_payload_t*)
|
||||
certreq_payload_create(CERTIFICATE_REQUEST_V1);
|
||||
|
||||
this->encoding = ENC_X509_SIGNATURE;
|
||||
this->data = chunk_clone(id->get_encoding(id));
|
||||
this->payload_length = get_header_length(this) + this->data.len;
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
|
|
@ -27,25 +27,20 @@ typedef struct certreq_payload_t certreq_payload_t;
|
|||
#include <library.h>
|
||||
#include <encoding/payloads/payload.h>
|
||||
#include <encoding/payloads/cert_payload.h>
|
||||
#include <utils/identification.h>
|
||||
|
||||
/**
|
||||
* Length of a CERTREQ payload without the CERTREQ data in bytes.
|
||||
*/
|
||||
#define CERTREQ_PAYLOAD_HEADER_LENGTH 5
|
||||
|
||||
/**
|
||||
* Class representing an IKEv2 CERTREQ payload.
|
||||
*
|
||||
* The CERTREQ payload format is described in RFC section 3.7.
|
||||
* Class representing an IKEv1/IKEv2 CERTREQ payload.
|
||||
*/
|
||||
struct certreq_payload_t {
|
||||
|
||||
/**
|
||||
* The payload_t interface.
|
||||
*/
|
||||
payload_t payload_interface;
|
||||
|
||||
/**
|
||||
* Create an enumerator over contained keyids.
|
||||
* Create an enumerator over contained keyids (IKEv2 only).
|
||||
*
|
||||
* @return enumerator over chunk_t's.
|
||||
*/
|
||||
|
@ -59,13 +54,20 @@ struct certreq_payload_t {
|
|||
certificate_type_t (*get_cert_type)(certreq_payload_t *this);
|
||||
|
||||
/**
|
||||
* Add a certificates keyid to the payload.
|
||||
* Add a certificates keyid to the payload (IKEv2 only).
|
||||
*
|
||||
* @param keyid keyid of the trusted certifcate
|
||||
* @return
|
||||
*/
|
||||
void (*add_keyid)(certreq_payload_t *this, chunk_t keyid);
|
||||
|
||||
/**
|
||||
* Get the distinguished name of the payload (IKEv1 only).
|
||||
*
|
||||
* @return DN as identity, must be destroyed
|
||||
*/
|
||||
identification_t* (*get_dn)(certreq_payload_t *this);
|
||||
|
||||
/**
|
||||
* Destroys an certreq_payload_t object.
|
||||
*/
|
||||
|
@ -77,14 +79,22 @@ struct certreq_payload_t {
|
|||
*
|
||||
* @return certreq payload
|
||||
*/
|
||||
certreq_payload_t *certreq_payload_create(void);
|
||||
certreq_payload_t *certreq_payload_create(payload_type_t payload_type);
|
||||
|
||||
/**
|
||||
* Creates an empty certreq_payload_t for a kind of certificates.
|
||||
* Creates an empty IKEv2 certreq_payload_t for a kind of certificates.
|
||||
*
|
||||
* @param type type of the added keyids
|
||||
* @return certreq payload
|
||||
*/
|
||||
certreq_payload_t *certreq_payload_create_type(certificate_type_t type);
|
||||
|
||||
/**
|
||||
* Creates a IKEv1 certreq_payload_t for a given distinguished name.
|
||||
*
|
||||
* @param id distinguished name, does not get owned
|
||||
* @return certreq payload
|
||||
*/
|
||||
certreq_payload_t *certreq_payload_create_dn(identification_t *id);
|
||||
|
||||
#endif /** CERTREQ_PAYLOAD_H_ @}*/
|
||||
|
|
|
@ -36,41 +36,48 @@ struct private_configuration_attribute_t {
|
|||
configuration_attribute_t public;
|
||||
|
||||
/**
|
||||
* Reserved bit
|
||||
* Value encoded in length field?
|
||||
*/
|
||||
bool af_flag;
|
||||
|
||||
/**
|
||||
* Reserved bit (af_flag in IKEv2)
|
||||
*/
|
||||
bool reserved;
|
||||
|
||||
/**
|
||||
* Type of the attribute.
|
||||
*/
|
||||
u_int16_t type;
|
||||
u_int16_t attr_type;
|
||||
|
||||
/**
|
||||
* Length of the attribute.
|
||||
* Length of the attribute, value if af_flag set.
|
||||
*/
|
||||
u_int16_t length;
|
||||
u_int16_t length_or_value;
|
||||
|
||||
/**
|
||||
* Attribute value as chunk.
|
||||
*/
|
||||
chunk_t value;
|
||||
|
||||
/**
|
||||
* Payload type, CONFIGURATION_ATTRIBUTE or DATA_ATTRIBUTE_V1
|
||||
*/
|
||||
payload_type_t type;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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 rules for a IKEv2 configuration attribute / IKEv1 data attribute
|
||||
*/
|
||||
encoding_rule_t configuration_attribute_encodings[] = {
|
||||
static encoding_rule_t encodings_v2[] = {
|
||||
/* 1 reserved bit */
|
||||
{ RESERVED_BIT, offsetof(private_configuration_attribute_t, reserved)},
|
||||
{ RESERVED_BIT, offsetof(private_configuration_attribute_t, reserved) },
|
||||
/* type of the attribute as 15 bit unsigned integer */
|
||||
{ ATTRIBUTE_TYPE, offsetof(private_configuration_attribute_t, type) },
|
||||
{ ATTRIBUTE_TYPE, offsetof(private_configuration_attribute_t, attr_type) },
|
||||
/* Length of attribute value */
|
||||
{ CONFIGURATION_ATTRIBUTE_LENGTH, offsetof(private_configuration_attribute_t, length) },
|
||||
{ ATTRIBUTE_LENGTH, offsetof(private_configuration_attribute_t, length_or_value)},
|
||||
/* Value of attribute if attribute format flag is zero */
|
||||
{ CONFIGURATION_ATTRIBUTE_VALUE, offsetof(private_configuration_attribute_t, value) }
|
||||
{ ATTRIBUTE_VALUE, offsetof(private_configuration_attribute_t, value) },
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -85,87 +92,142 @@ encoding_rule_t configuration_attribute_encodings[] = {
|
|||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
/**
|
||||
* Encoding rules for a IKEv1 data attribute
|
||||
*/
|
||||
static encoding_rule_t encodings_v1[] = {
|
||||
/* AF Flag */
|
||||
{ ATTRIBUTE_FORMAT, offsetof(private_configuration_attribute_t, af_flag) },
|
||||
/* type of the attribute as 15 bit unsigned integer */
|
||||
{ ATTRIBUTE_TYPE, offsetof(private_configuration_attribute_t, attr_type) },
|
||||
/* Length of attribute value */
|
||||
{ ATTRIBUTE_LENGTH_OR_VALUE, offsetof(private_configuration_attribute_t, length_or_value)},
|
||||
/* Value of attribute if attribute format flag is zero */
|
||||
{ ATTRIBUTE_VALUE, offsetof(private_configuration_attribute_t, 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
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
!F| Attribute Type ! Length |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| |
|
||||
~ Value ~
|
||||
| |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
|
||||
METHOD(payload_t, verify, status_t,
|
||||
private_configuration_attribute_t *this)
|
||||
{
|
||||
bool failed = FALSE;
|
||||
|
||||
if (this->length != this->value.len)
|
||||
switch (this->attr_type)
|
||||
{
|
||||
DBG1(DBG_ENC, "invalid attribute length");
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
switch (this->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:
|
||||
if (this->length != 0 && this->length != 4)
|
||||
case INTERNAL_IP4_ADDRESS:
|
||||
case INTERNAL_IP4_NETMASK:
|
||||
case INTERNAL_IP4_DNS:
|
||||
case INTERNAL_IP4_NBNS:
|
||||
case INTERNAL_ADDRESS_EXPIRY:
|
||||
case INTERNAL_IP4_DHCP:
|
||||
if (this->length_or_value != 0 && this->length_or_value != 4)
|
||||
{
|
||||
failed = TRUE;
|
||||
}
|
||||
break;
|
||||
case INTERNAL_IP4_SUBNET:
|
||||
if (this->length != 0 && this->length != 8)
|
||||
case INTERNAL_IP4_SUBNET:
|
||||
if (this->length_or_value != 0 && this->length_or_value != 8)
|
||||
{
|
||||
failed = TRUE;
|
||||
}
|
||||
break;
|
||||
case INTERNAL_IP6_ADDRESS:
|
||||
case INTERNAL_IP6_SUBNET:
|
||||
if (this->length != 0 && this->length != 17)
|
||||
case INTERNAL_IP6_ADDRESS:
|
||||
case INTERNAL_IP6_SUBNET:
|
||||
if (this->length_or_value != 0 && this->length_or_value != 17)
|
||||
{
|
||||
failed = TRUE;
|
||||
}
|
||||
break;
|
||||
case INTERNAL_IP6_DNS:
|
||||
case INTERNAL_IP6_NBNS:
|
||||
case INTERNAL_IP6_DHCP:
|
||||
if (this->length != 0 && this->length != 16)
|
||||
case INTERNAL_IP6_DNS:
|
||||
case INTERNAL_IP6_NBNS:
|
||||
case INTERNAL_IP6_DHCP:
|
||||
if (this->length_or_value != 0 && this->length_or_value != 16)
|
||||
{
|
||||
failed = TRUE;
|
||||
}
|
||||
break;
|
||||
case SUPPORTED_ATTRIBUTES:
|
||||
if (this->length % 2)
|
||||
case SUPPORTED_ATTRIBUTES:
|
||||
if (this->length_or_value % 2)
|
||||
{
|
||||
failed = TRUE;
|
||||
}
|
||||
break;
|
||||
case APPLICATION_VERSION:
|
||||
case APPLICATION_VERSION:
|
||||
case INTERNAL_IP4_SERVER:
|
||||
case INTERNAL_IP6_SERVER:
|
||||
case XAUTH_TYPE:
|
||||
case XAUTH_USER_NAME:
|
||||
case XAUTH_USER_PASSWORD:
|
||||
case XAUTH_PASSCODE:
|
||||
case XAUTH_MESSAGE:
|
||||
case XAUTH_CHALLENGE:
|
||||
case XAUTH_DOMAIN:
|
||||
case XAUTH_STATUS:
|
||||
case XAUTH_NEXT_PIN:
|
||||
case XAUTH_ANSWER:
|
||||
case UNITY_BANNER:
|
||||
case UNITY_SAVE_PASSWD:
|
||||
case UNITY_DEF_DOMAIN:
|
||||
case UNITY_SPLITDNS_NAME:
|
||||
case UNITY_SPLIT_INCLUDE:
|
||||
case UNITY_NATT_PORT:
|
||||
case UNITY_LOCAL_LAN:
|
||||
case UNITY_PFS:
|
||||
case UNITY_FW_TYPE:
|
||||
case UNITY_BACKUP_SERVERS:
|
||||
case UNITY_DDNS_HOSTNAME:
|
||||
/* any length acceptable */
|
||||
break;
|
||||
default:
|
||||
default:
|
||||
DBG1(DBG_ENC, "unknown attribute type %N",
|
||||
configuration_attribute_type_names, this->type);
|
||||
configuration_attribute_type_names, this->attr_type);
|
||||
break;
|
||||
}
|
||||
|
||||
if (failed)
|
||||
{
|
||||
DBG1(DBG_ENC, "invalid attribute length %d for %N",
|
||||
this->length, configuration_attribute_type_names, this->type);
|
||||
this->length_or_value, configuration_attribute_type_names,
|
||||
this->attr_type);
|
||||
return FAILED;
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_encoding_rules, void,
|
||||
private_configuration_attribute_t *this, encoding_rule_t **rules,
|
||||
size_t *rule_count)
|
||||
METHOD(payload_t, get_encoding_rules, int,
|
||||
private_configuration_attribute_t *this, encoding_rule_t **rules)
|
||||
{
|
||||
*rules = configuration_attribute_encodings;
|
||||
*rule_count = countof(configuration_attribute_encodings);
|
||||
if (this->type == CONFIGURATION_ATTRIBUTE)
|
||||
{
|
||||
*rules = encodings_v2;
|
||||
return countof(encodings_v2);
|
||||
}
|
||||
*rules = encodings_v1;
|
||||
return countof(encodings_v1);
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_header_length, int,
|
||||
private_configuration_attribute_t *this)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_type, payload_type_t,
|
||||
private_configuration_attribute_t *this)
|
||||
{
|
||||
return CONFIGURATION_ATTRIBUTE;
|
||||
return this->type;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_next_type, payload_type_t,
|
||||
|
@ -182,21 +244,35 @@ METHOD(payload_t, set_next_type, void,
|
|||
METHOD(payload_t, get_length, size_t,
|
||||
private_configuration_attribute_t *this)
|
||||
{
|
||||
return this->value.len + CONFIGURATION_ATTRIBUTE_HEADER_LENGTH;
|
||||
return get_header_length(this) + this->value.len;
|
||||
}
|
||||
|
||||
METHOD(configuration_attribute_t, get_cattr_type, configuration_attribute_type_t,
|
||||
private_configuration_attribute_t *this)
|
||||
{
|
||||
return this->type;
|
||||
return this->attr_type;
|
||||
}
|
||||
|
||||
METHOD(configuration_attribute_t, get_value, chunk_t,
|
||||
METHOD(configuration_attribute_t, get_chunk, chunk_t,
|
||||
private_configuration_attribute_t *this)
|
||||
{
|
||||
if (this->af_flag)
|
||||
{
|
||||
return chunk_from_thing(this->length_or_value);
|
||||
}
|
||||
return this->value;
|
||||
}
|
||||
|
||||
METHOD(configuration_attribute_t, get_value, u_int16_t,
|
||||
private_configuration_attribute_t *this)
|
||||
{
|
||||
if (this->af_flag)
|
||||
{
|
||||
return this->length_or_value;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
METHOD2(payload_t, configuration_attribute_t, destroy, void,
|
||||
private_configuration_attribute_t *this)
|
||||
{
|
||||
|
@ -207,7 +283,7 @@ METHOD2(payload_t, configuration_attribute_t, destroy, void,
|
|||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
configuration_attribute_t *configuration_attribute_create()
|
||||
configuration_attribute_t *configuration_attribute_create(payload_type_t type)
|
||||
{
|
||||
private_configuration_attribute_t *this;
|
||||
|
||||
|
@ -216,16 +292,19 @@ configuration_attribute_t *configuration_attribute_create()
|
|||
.payload_interface = {
|
||||
.verify = _verify,
|
||||
.get_encoding_rules = _get_encoding_rules,
|
||||
.get_header_length = _get_header_length,
|
||||
.get_length = _get_length,
|
||||
.get_next_type = _get_next_type,
|
||||
.set_next_type = _set_next_type,
|
||||
.get_type = _get_type,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.get_chunk = _get_chunk,
|
||||
.get_value = _get_value,
|
||||
.get_type = _get_cattr_type,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.type = type
|
||||
);
|
||||
return &this->public;
|
||||
}
|
||||
|
@ -233,15 +312,33 @@ configuration_attribute_t *configuration_attribute_create()
|
|||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
configuration_attribute_t *configuration_attribute_create_value(
|
||||
configuration_attribute_type_t type, chunk_t value)
|
||||
configuration_attribute_t *configuration_attribute_create_chunk(
|
||||
payload_type_t type, configuration_attribute_type_t attr_type, chunk_t chunk)
|
||||
{
|
||||
private_configuration_attribute_t *this;
|
||||
|
||||
this = (private_configuration_attribute_t*)configuration_attribute_create();
|
||||
this->type = ((u_int16_t)type) & 0x7FFF;
|
||||
this->value = chunk_clone(value);
|
||||
this->length = value.len;
|
||||
this = (private_configuration_attribute_t*)
|
||||
configuration_attribute_create(type);
|
||||
this->attr_type = ((u_int16_t)attr_type) & 0x7FFF;
|
||||
this->value = chunk_clone(chunk);
|
||||
this->length_or_value = chunk.len;
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
configuration_attribute_t *configuration_attribute_create_value(
|
||||
configuration_attribute_type_t attr_type, u_int16_t value)
|
||||
{
|
||||
private_configuration_attribute_t *this;
|
||||
|
||||
this = (private_configuration_attribute_t*)
|
||||
configuration_attribute_create(CONFIGURATION_ATTRIBUTE_V1);
|
||||
this->attr_type = ((u_int16_t)attr_type) & 0x7FFF;
|
||||
this->length_or_value = value;
|
||||
this->af_flag = TRUE;
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
|
|
@ -29,14 +29,7 @@ typedef struct configuration_attribute_t configuration_attribute_t;
|
|||
#include <encoding/payloads/payload.h>
|
||||
|
||||
/**
|
||||
* Configuration attribute header length in bytes.
|
||||
*/
|
||||
#define CONFIGURATION_ATTRIBUTE_HEADER_LENGTH 4
|
||||
|
||||
/**
|
||||
* Class representing an IKEv2-CONFIGURATION Attribute.
|
||||
*
|
||||
* The CONFIGURATION ATTRIBUTE format is described in RFC section 3.15.1.
|
||||
* Class representing an IKEv2 configuration attribute / IKEv1 data attribute.
|
||||
*/
|
||||
struct configuration_attribute_t {
|
||||
|
||||
|
@ -53,11 +46,18 @@ struct configuration_attribute_t {
|
|||
configuration_attribute_type_t (*get_type)(configuration_attribute_t *this);
|
||||
|
||||
/**
|
||||
* Returns the value of the attribute.
|
||||
* Returns the value of the attribute as chunk.
|
||||
*
|
||||
* @return chunk_t pointing to the internal value
|
||||
*/
|
||||
chunk_t (*get_value) (configuration_attribute_t *this);
|
||||
chunk_t (*get_chunk) (configuration_attribute_t *this);
|
||||
|
||||
/**
|
||||
* Returns the 2 byte value of the attribute as u_int16.
|
||||
*
|
||||
* @return attribute value
|
||||
*/
|
||||
u_int16_t (*get_value) (configuration_attribute_t *this);
|
||||
|
||||
/**
|
||||
* Destroys an configuration_attribute_t object.
|
||||
|
@ -68,18 +68,30 @@ struct configuration_attribute_t {
|
|||
/**
|
||||
* Creates an empty configuration attribute.
|
||||
*
|
||||
* @return created configuration attribute
|
||||
* @param type CONFIGURATION_ATTRIBUTE or CONFIGURATION_ATTRIBUTE_V1
|
||||
* @return created configuration attribute
|
||||
*/
|
||||
configuration_attribute_t *configuration_attribute_create();
|
||||
configuration_attribute_t *configuration_attribute_create(payload_type_t type);
|
||||
|
||||
/**
|
||||
* Creates a configuration attribute with type and value.
|
||||
*
|
||||
* @param type type of configuration attribute
|
||||
* @param value value, gets cloned
|
||||
* @return created configuration attribute
|
||||
* @param type CONFIGURATION_ATTRIBUTE or CONFIGURATION_ATTRIBUTE_V1
|
||||
* @param attr_type type of configuration attribute
|
||||
* @param chunk attribute value, gets cloned
|
||||
* @return created configuration attribute
|
||||
*/
|
||||
configuration_attribute_t *configuration_attribute_create_chunk(
|
||||
payload_type_t type, configuration_attribute_type_t attr_type, chunk_t chunk);
|
||||
|
||||
/**
|
||||
* Creates a IKEv1 configuration attribute with 2 bytes value (IKEv1 only).
|
||||
*
|
||||
* @param attr_type type of configuration attribute
|
||||
* @param value attribute value, gets cloned
|
||||
* @return created CONFIGURATION_ATTRIBUTE_V1 configuration attribute
|
||||
*/
|
||||
configuration_attribute_t *configuration_attribute_create_value(
|
||||
configuration_attribute_type_t type, chunk_t value);
|
||||
configuration_attribute_type_t attr_type, u_int16_t value);
|
||||
|
||||
#endif /** CONFIGURATION_ATTRIBUTE_H_ @}*/
|
||||
|
|
|
@ -44,7 +44,7 @@ struct private_cp_payload_t {
|
|||
/**
|
||||
* Next payload type.
|
||||
*/
|
||||
u_int8_t next_payload;
|
||||
u_int8_t next_payload;
|
||||
|
||||
/**
|
||||
* Critical flag.
|
||||
|
@ -66,6 +66,11 @@ struct private_cp_payload_t {
|
|||
*/
|
||||
u_int16_t payload_length;
|
||||
|
||||
/**
|
||||
* Identifier field, IKEv1 only
|
||||
*/
|
||||
u_int16_t identifier;
|
||||
|
||||
/**
|
||||
* List of attributes, as configuration_attribute_t
|
||||
*/
|
||||
|
@ -74,38 +79,40 @@ struct private_cp_payload_t {
|
|||
/**
|
||||
* Config Type.
|
||||
*/
|
||||
u_int8_t type;
|
||||
u_int8_t cfg_type;
|
||||
|
||||
/**
|
||||
* CONFIGURATION or CONFIGURATION_V1
|
||||
*/
|
||||
payload_type_t type;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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 rules to for an IKEv2 configuration payload
|
||||
*/
|
||||
encoding_rule_t cp_payload_encodings[] = {
|
||||
static encoding_rule_t encodings_v2[] = {
|
||||
/* 1 Byte next payload type, stored in the field next_payload */
|
||||
{ U_INT_8, offsetof(private_cp_payload_t, next_payload) },
|
||||
{ U_INT_8, offsetof(private_cp_payload_t, next_payload) },
|
||||
/* the critical bit */
|
||||
{ FLAG, offsetof(private_cp_payload_t, critical) },
|
||||
{ FLAG, offsetof(private_cp_payload_t, critical) },
|
||||
/* 7 Bit reserved bits */
|
||||
{ RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[0]) },
|
||||
{ RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[1]) },
|
||||
{ RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[2]) },
|
||||
{ RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[3]) },
|
||||
{ RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[4]) },
|
||||
{ RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[5]) },
|
||||
{ RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[6]) },
|
||||
{ RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[0]) },
|
||||
{ RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[1]) },
|
||||
{ RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[2]) },
|
||||
{ RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[3]) },
|
||||
{ RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[4]) },
|
||||
{ RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[5]) },
|
||||
{ RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[6]) },
|
||||
/* 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, type) },
|
||||
{ PAYLOAD_LENGTH, offsetof(private_cp_payload_t, payload_length) },
|
||||
{ U_INT_8, offsetof(private_cp_payload_t, cfg_type) },
|
||||
/* 3 reserved bytes */
|
||||
{ RESERVED_BYTE, offsetof(private_cp_payload_t, reserved_byte[0])},
|
||||
{ RESERVED_BYTE, offsetof(private_cp_payload_t, reserved_byte[1])},
|
||||
{ RESERVED_BYTE, offsetof(private_cp_payload_t, reserved_byte[2])},
|
||||
{ CONFIGURATION_ATTRIBUTES, offsetof(private_cp_payload_t, attributes) }
|
||||
{ RESERVED_BYTE, offsetof(private_cp_payload_t, reserved_byte[0])},
|
||||
{ RESERVED_BYTE, offsetof(private_cp_payload_t, reserved_byte[1])},
|
||||
{ RESERVED_BYTE, offsetof(private_cp_payload_t, reserved_byte[2])},
|
||||
/* list of configuration attributes in a list */
|
||||
{ PAYLOAD_LIST + CONFIGURATION_ATTRIBUTE,
|
||||
offsetof(private_cp_payload_t, attributes) },
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -122,6 +129,47 @@ encoding_rule_t cp_payload_encodings[] = {
|
|||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
/**
|
||||
* Encoding rules to for an IKEv1 configuration payload
|
||||
*/
|
||||
static encoding_rule_t encodings_v1[] = {
|
||||
/* 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 */
|
||||
{ RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[0]) },
|
||||
{ RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[1]) },
|
||||
{ RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[2]) },
|
||||
{ RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[3]) },
|
||||
{ RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[4]) },
|
||||
{ RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[5]) },
|
||||
{ RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[6]) },
|
||||
/* Length of the whole CP payload*/
|
||||
{ PAYLOAD_LENGTH, offsetof(private_cp_payload_t, payload_length) },
|
||||
{ U_INT_8, offsetof(private_cp_payload_t, cfg_type) },
|
||||
/* 1 reserved bytes */
|
||||
{ RESERVED_BYTE, offsetof(private_cp_payload_t, reserved_byte[0])},
|
||||
{ U_INT_16, offsetof(private_cp_payload_t, identifier)},
|
||||
/* list of configuration attributes in a list */
|
||||
{ PAYLOAD_LIST + CONFIGURATION_ATTRIBUTE_V1,
|
||||
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 ! RESERVED ! Payload Length !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! CFG Type ! RESERVED ! Identifier !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! !
|
||||
~ Configuration Attributes ~
|
||||
! !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
METHOD(payload_t, verify, status_t,
|
||||
private_cp_payload_t *this)
|
||||
{
|
||||
|
@ -142,17 +190,28 @@ METHOD(payload_t, verify, status_t,
|
|||
return status;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_encoding_rules, void,
|
||||
private_cp_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
|
||||
METHOD(payload_t, get_encoding_rules, int,
|
||||
private_cp_payload_t *this, encoding_rule_t **rules)
|
||||
{
|
||||
*rules = cp_payload_encodings;
|
||||
*rule_count = countof(cp_payload_encodings);
|
||||
if (this->type == CONFIGURATION)
|
||||
{
|
||||
*rules = encodings_v2;
|
||||
return countof(encodings_v2);
|
||||
}
|
||||
*rules = encodings_v1;
|
||||
return countof(encodings_v1);
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_header_length, int,
|
||||
private_cp_payload_t *this)
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_type, payload_type_t,
|
||||
private_cp_payload_t *this)
|
||||
{
|
||||
return CONFIGURATION;
|
||||
return this->type;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_next_type, payload_type_t,
|
||||
|
@ -175,7 +234,7 @@ static void compute_length(private_cp_payload_t *this)
|
|||
enumerator_t *enumerator;
|
||||
payload_t *attribute;
|
||||
|
||||
this->payload_length = CP_PAYLOAD_HEADER_LENGTH;
|
||||
this->payload_length = get_header_length(this);
|
||||
|
||||
enumerator = this->attributes->create_enumerator(this->attributes);
|
||||
while (enumerator->enumerate(enumerator, &attribute))
|
||||
|
@ -207,7 +266,18 @@ METHOD(cp_payload_t, add_attribute, void,
|
|||
METHOD(cp_payload_t, get_config_type, config_type_t,
|
||||
private_cp_payload_t *this)
|
||||
{
|
||||
return this->type;
|
||||
return this->cfg_type;
|
||||
}
|
||||
|
||||
METHOD(cp_payload_t, get_identifier, u_int16_t,
|
||||
private_cp_payload_t *this)
|
||||
{
|
||||
return this->identifier;
|
||||
}
|
||||
METHOD(cp_payload_t, set_identifier, void,
|
||||
private_cp_payload_t *this, u_int16_t identifier)
|
||||
{
|
||||
this->identifier = identifier;
|
||||
}
|
||||
|
||||
METHOD2(payload_t, cp_payload_t, destroy, void,
|
||||
|
@ -221,7 +291,7 @@ METHOD2(payload_t, cp_payload_t, destroy, void,
|
|||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
cp_payload_t *cp_payload_create_type(config_type_t type)
|
||||
cp_payload_t *cp_payload_create_type(payload_type_t type, config_type_t cfg_type)
|
||||
{
|
||||
private_cp_payload_t *this;
|
||||
|
||||
|
@ -230,6 +300,7 @@ cp_payload_t *cp_payload_create_type(config_type_t type)
|
|||
.payload_interface = {
|
||||
.verify = _verify,
|
||||
.get_encoding_rules = _get_encoding_rules,
|
||||
.get_header_length = _get_header_length,
|
||||
.get_length = _get_length,
|
||||
.get_next_type = _get_next_type,
|
||||
.set_next_type = _set_next_type,
|
||||
|
@ -239,11 +310,14 @@ cp_payload_t *cp_payload_create_type(config_type_t type)
|
|||
.create_attribute_enumerator = _create_attribute_enumerator,
|
||||
.add_attribute = _add_attribute,
|
||||
.get_type = _get_config_type,
|
||||
.get_identifier = _get_identifier,
|
||||
.set_identifier = _set_identifier,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.next_payload = NO_PAYLOAD,
|
||||
.payload_length = CP_PAYLOAD_HEADER_LENGTH,
|
||||
.payload_length = get_header_length(this),
|
||||
.attributes = linked_list_create(),
|
||||
.cfg_type = cfg_type,
|
||||
.type = type,
|
||||
);
|
||||
return &this->public;
|
||||
|
@ -252,7 +326,7 @@ cp_payload_t *cp_payload_create_type(config_type_t type)
|
|||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
cp_payload_t *cp_payload_create()
|
||||
cp_payload_t *cp_payload_create(payload_type_t type)
|
||||
{
|
||||
return cp_payload_create_type(CFG_REQUEST);
|
||||
return cp_payload_create_type(type, CFG_REQUEST);
|
||||
}
|
||||
|
|
|
@ -30,11 +30,6 @@ typedef struct cp_payload_t cp_payload_t;
|
|||
#include <encoding/payloads/configuration_attribute.h>
|
||||
#include <utils/enumerator.h>
|
||||
|
||||
/**
|
||||
* CP_PAYLOAD length in bytes without any proposal substructure.
|
||||
*/
|
||||
#define CP_PAYLOAD_HEADER_LENGTH 8
|
||||
|
||||
/**
|
||||
* Config Type of an Configuration Payload.
|
||||
*/
|
||||
|
@ -51,9 +46,7 @@ enum config_type_t {
|
|||
extern enum_name_t *config_type_names;
|
||||
|
||||
/**
|
||||
* Class representing an IKEv2-CP Payload.
|
||||
*
|
||||
* The CP Payload format is described in RFC section 3.15.
|
||||
* Class representing an IKEv2 configuration / IKEv1 attribute payload.
|
||||
*/
|
||||
struct cp_payload_t {
|
||||
|
||||
|
@ -84,6 +77,20 @@ struct cp_payload_t {
|
|||
*/
|
||||
config_type_t (*get_type) (cp_payload_t *this);
|
||||
|
||||
/**
|
||||
* Set the configuration payload identifier (IKEv1 only).
|
||||
*
|
||||
@param identifier identifier to set
|
||||
*/
|
||||
void (*set_identifier) (cp_payload_t *this, u_int16_t identifier);
|
||||
|
||||
/**
|
||||
* Get the configuration payload identifier (IKEv1 only).
|
||||
*
|
||||
* @return identifier
|
||||
*/
|
||||
u_int16_t (*get_identifier) (cp_payload_t *this);
|
||||
|
||||
/**
|
||||
* Destroys an cp_payload_t object.
|
||||
*/
|
||||
|
@ -93,16 +100,18 @@ struct cp_payload_t {
|
|||
/**
|
||||
* Creates an empty configuration payload
|
||||
*
|
||||
* @return empty configuration payload
|
||||
* @param type payload type, CONFIGURATION or CONFIGURATION_V1
|
||||
* @return empty configuration payload
|
||||
*/
|
||||
cp_payload_t *cp_payload_create();
|
||||
cp_payload_t *cp_payload_create(payload_type_t type);
|
||||
|
||||
/**
|
||||
* Creates an cp_payload_t with type and value
|
||||
*
|
||||
* @param config_type type of configuration payload to create
|
||||
* @return created configuration payload
|
||||
* @param type payload type, CONFIGURATION or CONFIGURATION_V1
|
||||
* @param cfg_type type of configuration payload to create
|
||||
* @return created configuration payload
|
||||
*/
|
||||
cp_payload_t *cp_payload_create_type(config_type_t config_type);
|
||||
cp_payload_t *cp_payload_create_type(payload_type_t type, config_type_t cfg_type);
|
||||
|
||||
#endif /** CP_PAYLOAD_H_ @}*/
|
||||
|
|
|
@ -24,9 +24,9 @@ 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.
|
||||
*/
|
||||
|
@ -45,13 +45,18 @@ struct private_delete_payload_t {
|
|||
/**
|
||||
* reserved bits
|
||||
*/
|
||||
bool reserved[7];
|
||||
bool reserved[8];
|
||||
|
||||
/**
|
||||
* Length of this payload.
|
||||
*/
|
||||
u_int16_t payload_length;
|
||||
|
||||
/**
|
||||
* IKEv1 Domain of Interpretation
|
||||
*/
|
||||
u_int32_t doi;
|
||||
|
||||
/**
|
||||
* Protocol ID.
|
||||
*/
|
||||
|
@ -71,19 +76,21 @@ struct private_delete_payload_t {
|
|||
* The contained SPI's.
|
||||
*/
|
||||
chunk_t spis;
|
||||
|
||||
/**
|
||||
* Payload type, DELETE or DELETE_V1
|
||||
*/
|
||||
payload_type_t type;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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 rules for an IKEv2 delete payload.
|
||||
*/
|
||||
encoding_rule_t delete_payload_encodings[] = {
|
||||
static encoding_rule_t encodings_v2[] = {
|
||||
/* 1 Byte next payload type, stored in the field next_payload */
|
||||
{ U_INT_8, offsetof(private_delete_payload_t, next_payload) },
|
||||
{ U_INT_8, offsetof(private_delete_payload_t, next_payload) },
|
||||
/* the critical bit */
|
||||
{ FLAG, offsetof(private_delete_payload_t, critical) },
|
||||
{ FLAG, offsetof(private_delete_payload_t, critical) },
|
||||
/* 7 Bit reserved bits */
|
||||
{ RESERVED_BIT, offsetof(private_delete_payload_t, reserved[0]) },
|
||||
{ RESERVED_BIT, offsetof(private_delete_payload_t, reserved[1]) },
|
||||
|
@ -98,7 +105,7 @@ encoding_rule_t delete_payload_encodings[] = {
|
|||
{ 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) }
|
||||
{ CHUNK_DATA, offsetof(private_delete_payload_t, spis) },
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -115,6 +122,48 @@ encoding_rule_t delete_payload_encodings[] = {
|
|||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
/**
|
||||
* Encoding rules for an IKEv1 delete payload.
|
||||
*/
|
||||
static encoding_rule_t encodings_v1[] = {
|
||||
/* 1 Byte next payload type, stored in the field next_payload */
|
||||
{ U_INT_8, offsetof(private_delete_payload_t, next_payload) },
|
||||
/* 8 Bit reserved bits */
|
||||
{ RESERVED_BIT, offsetof(private_delete_payload_t, reserved[0]) },
|
||||
{ RESERVED_BIT, offsetof(private_delete_payload_t, reserved[1]) },
|
||||
{ RESERVED_BIT, offsetof(private_delete_payload_t, reserved[2]) },
|
||||
{ RESERVED_BIT, offsetof(private_delete_payload_t, reserved[3]) },
|
||||
{ RESERVED_BIT, offsetof(private_delete_payload_t, reserved[4]) },
|
||||
{ RESERVED_BIT, offsetof(private_delete_payload_t, reserved[5]) },
|
||||
{ RESERVED_BIT, offsetof(private_delete_payload_t, reserved[6]) },
|
||||
{ RESERVED_BIT, offsetof(private_delete_payload_t, reserved[7]) },
|
||||
/* Length of the whole payload*/
|
||||
{ PAYLOAD_LENGTH, offsetof(private_delete_payload_t, payload_length) },
|
||||
/* Domain of interpretation */
|
||||
{ U_INT_32, offsetof(private_delete_payload_t, doi) },
|
||||
{ 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 */
|
||||
{ CHUNK_DATA, 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 !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! DOI !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! Protocol ID ! SPI Size ! # of SPIs !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! !
|
||||
~ Security Parameter Index(es) (SPI) ~
|
||||
! !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
METHOD(payload_t, verify, status_t,
|
||||
private_delete_payload_t *this)
|
||||
{
|
||||
|
@ -129,10 +178,19 @@ METHOD(payload_t, verify, status_t,
|
|||
break;
|
||||
case PROTO_IKE:
|
||||
case 0:
|
||||
/* IKE deletion has no spi assigned! */
|
||||
if (this->spi_size != 0)
|
||||
{
|
||||
return FAILED;
|
||||
if (this->type == DELETE)
|
||||
{ /* IKEv2 deletion has no spi assigned! */
|
||||
if (this->spi_size != 0)
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ /* IKEv1 uses the two concatenated ISAKMP cookies as SPI */
|
||||
if (this->spi_size != 16)
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -145,17 +203,32 @@ METHOD(payload_t, verify, status_t,
|
|||
return SUCCESS;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_encoding_rules, void,
|
||||
private_delete_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
|
||||
METHOD(payload_t, get_encoding_rules, int,
|
||||
private_delete_payload_t *this, encoding_rule_t **rules)
|
||||
{
|
||||
*rules = delete_payload_encodings;
|
||||
*rule_count = countof(delete_payload_encodings);
|
||||
if (this->type == DELETE)
|
||||
{
|
||||
*rules = encodings_v2;
|
||||
return countof(encodings_v2);
|
||||
}
|
||||
*rules = encodings_v1;
|
||||
return countof(encodings_v1);
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_header_length, int,
|
||||
private_delete_payload_t *this)
|
||||
{
|
||||
if (this->type == DELETE)
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
return 12;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_payload_type, payload_type_t,
|
||||
private_delete_payload_t *this)
|
||||
{
|
||||
return DELETE;
|
||||
return this->type;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_next_type, payload_type_t,
|
||||
|
@ -198,6 +271,16 @@ METHOD(delete_payload_t, add_spi, void,
|
|||
}
|
||||
}
|
||||
|
||||
METHOD(delete_payload_t, set_ike_spi, void,
|
||||
private_delete_payload_t *this, u_int64_t spi_i, u_int64_t spi_r)
|
||||
{
|
||||
free(this->spis.ptr);
|
||||
this->spis = chunk_cat("cc", chunk_from_thing(spi_i),
|
||||
chunk_from_thing(spi_r));
|
||||
this->spi_count = 1;
|
||||
this->payload_length = get_header_length(this) + this->spi_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* SPI enumerator implementation
|
||||
*/
|
||||
|
@ -249,7 +332,8 @@ METHOD2(payload_t, delete_payload_t, destroy, void,
|
|||
/*
|
||||
* Described in header
|
||||
*/
|
||||
delete_payload_t *delete_payload_create(protocol_id_t protocol_id)
|
||||
delete_payload_t *delete_payload_create(payload_type_t type,
|
||||
protocol_id_t protocol_id)
|
||||
{
|
||||
private_delete_payload_t *this;
|
||||
|
||||
|
@ -258,6 +342,7 @@ delete_payload_t *delete_payload_create(protocol_id_t protocol_id)
|
|||
.payload_interface = {
|
||||
.verify = _verify,
|
||||
.get_encoding_rules = _get_encoding_rules,
|
||||
.get_header_length = _get_header_length,
|
||||
.get_length = _get_length,
|
||||
.get_next_type = _get_next_type,
|
||||
.set_next_type = _set_next_type,
|
||||
|
@ -266,13 +351,27 @@ delete_payload_t *delete_payload_create(protocol_id_t protocol_id)
|
|||
},
|
||||
.get_protocol_id = _get_protocol_id,
|
||||
.add_spi = _add_spi,
|
||||
.set_ike_spi = _set_ike_spi,
|
||||
.create_spi_enumerator = _create_spi_enumerator,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.next_payload = NO_PAYLOAD,
|
||||
.payload_length = DELETE_PAYLOAD_HEADER_LENGTH,
|
||||
.protocol_id = protocol_id,
|
||||
.spi_size = protocol_id == PROTO_AH || protocol_id == PROTO_ESP ? 4 : 0,
|
||||
.doi = IKEV1_DOI_IPSEC,
|
||||
.type = type,
|
||||
);
|
||||
this->payload_length = get_header_length(this);
|
||||
|
||||
if (protocol_id == PROTO_IKE)
|
||||
{
|
||||
if (type == DELETE_V1)
|
||||
{
|
||||
this->spi_size = 16;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this->spi_size = 4;
|
||||
}
|
||||
return &this->public;
|
||||
}
|
||||
|
|
|
@ -29,14 +29,7 @@ typedef struct delete_payload_t delete_payload_t;
|
|||
#include <encoding/payloads/proposal_substructure.h>
|
||||
|
||||
/**
|
||||
* Length of a delete payload without the SPI in bytes.
|
||||
*/
|
||||
#define DELETE_PAYLOAD_HEADER_LENGTH 8
|
||||
|
||||
/**
|
||||
* Class representing an IKEv2 DELETE payload.
|
||||
*
|
||||
* The DELETE payload format is described in RFC section 3.11.
|
||||
* Class representing an IKEv1 or a IKEv2 DELETE payload.
|
||||
*/
|
||||
struct delete_payload_t {
|
||||
|
||||
|
@ -59,6 +52,14 @@ struct delete_payload_t {
|
|||
*/
|
||||
void (*add_spi) (delete_payload_t *this, u_int32_t spi);
|
||||
|
||||
/**
|
||||
* Set the IKE SPIs for an IKEv1 delete.
|
||||
*
|
||||
* @param spi_i initiator SPI
|
||||
* @param spi_r responder SPI
|
||||
*/
|
||||
void (*set_ike_spi)(delete_payload_t *this, u_int64_t spi_i, u_int64_t spi_r);
|
||||
|
||||
/**
|
||||
* Get an enumerator over the SPIs in network order.
|
||||
*
|
||||
|
@ -75,9 +76,11 @@ struct delete_payload_t {
|
|||
/**
|
||||
* Creates an empty delete_payload_t object.
|
||||
*
|
||||
* @param type DELETE or DELETE_V1
|
||||
* @param protocol_id protocol, such as AH|ESP
|
||||
* @return delete_payload_t object
|
||||
*/
|
||||
delete_payload_t *delete_payload_create(protocol_id_t protocol_id);
|
||||
delete_payload_t *delete_payload_create(payload_type_t type,
|
||||
protocol_id_t protocol_id);
|
||||
|
||||
#endif /** DELETE_PAYLOAD_H_ @}*/
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "eap_payload.h"
|
||||
|
||||
#include <daemon.h>
|
||||
#include <eap/eap.h>
|
||||
|
||||
typedef struct private_eap_payload_t private_eap_payload_t;
|
||||
|
||||
|
@ -65,7 +66,7 @@ struct private_eap_payload_t {
|
|||
* private_eap_payload_t.
|
||||
*
|
||||
*/
|
||||
static encoding_rule_t eap_payload_encodings[] = {
|
||||
static encoding_rule_t 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 */
|
||||
|
@ -81,7 +82,7 @@ static encoding_rule_t eap_payload_encodings[] = {
|
|||
/* Length of the whole payload*/
|
||||
{ PAYLOAD_LENGTH, offsetof(private_eap_payload_t, payload_length) },
|
||||
/* chunt to data, starting at "code" */
|
||||
{ EAP_DATA, offsetof(private_eap_payload_t, data) },
|
||||
{ CHUNK_DATA, offsetof(private_eap_payload_t, data) },
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -143,11 +144,17 @@ METHOD(payload_t, verify, status_t,
|
|||
return SUCCESS;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_encoding_rules, void,
|
||||
private_eap_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
|
||||
METHOD(payload_t, get_encoding_rules, int,
|
||||
private_eap_payload_t *this, encoding_rule_t **rules)
|
||||
{
|
||||
*rules = eap_payload_encodings;
|
||||
*rule_count = sizeof(eap_payload_encodings) / sizeof(encoding_rule_t);
|
||||
*rules = encodings;
|
||||
return countof(encodings);
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_header_length, int,
|
||||
private_eap_payload_t *this)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_payload_type, payload_type_t,
|
||||
|
@ -251,6 +258,7 @@ eap_payload_t *eap_payload_create()
|
|||
.payload_interface = {
|
||||
.verify = _verify,
|
||||
.get_encoding_rules = _get_encoding_rules,
|
||||
.get_header_length = _get_header_length,
|
||||
.get_length = _get_length,
|
||||
.get_next_type = _get_next_type,
|
||||
.set_next_type = _set_next_type,
|
||||
|
@ -265,7 +273,7 @@ eap_payload_t *eap_payload_create()
|
|||
.destroy = _destroy,
|
||||
},
|
||||
.next_payload = NO_PAYLOAD,
|
||||
.payload_length = EAP_PAYLOAD_HEADER_LENGTH,
|
||||
.payload_length = get_header_length(this),
|
||||
);
|
||||
return &this->public;
|
||||
}
|
||||
|
|
|
@ -25,13 +25,8 @@
|
|||
typedef struct eap_payload_t eap_payload_t;
|
||||
|
||||
#include <library.h>
|
||||
#include <eap/eap.h>
|
||||
#include <encoding/payloads/payload.h>
|
||||
#include <sa/authenticators/eap/eap_method.h>
|
||||
|
||||
/**
|
||||
* Length of a EAP payload without the EAP Message in bytes.
|
||||
*/
|
||||
#define EAP_PAYLOAD_HEADER_LENGTH 4
|
||||
|
||||
/**
|
||||
* Class representing an IKEv2 EAP payload.
|
||||
|
|
|
@ -29,30 +29,14 @@ ENUM(encoding_type_names, U_INT_4, ENCRYPTED_DATA,
|
|||
"HEADER_LENGTH",
|
||||
"SPI_SIZE",
|
||||
"SPI",
|
||||
"KEY_EXCHANGE_DATA",
|
||||
"NOTIFICATION_DATA",
|
||||
"PROPOSALS",
|
||||
"TRANSFORMS",
|
||||
"TRANSFORM_ATTRIBUTES",
|
||||
"CONFIGURATION_ATTRIBUTES",
|
||||
"CONFIGURATION_ATTRIBUTE_VALUE",
|
||||
"ATTRIBUTE_FORMAT",
|
||||
"ATTRIBUTE_TYPE",
|
||||
"ATTRIBUTE_LENGTH_OR_VALUE",
|
||||
"CONFIGURATION_ATTRIBUTE_LENGTH",
|
||||
"ATTRIBUTE_LENGTH",
|
||||
"ATTRIBUTE_VALUE",
|
||||
"TRAFFIC_SELECTORS",
|
||||
"TS_TYPE",
|
||||
"ADDRESS",
|
||||
"NONCE_DATA",
|
||||
"ID_DATA",
|
||||
"AUTH_DATA",
|
||||
"CERT_DATA",
|
||||
"CERTREQ_DATA",
|
||||
"EAP_DATA",
|
||||
"SPIS",
|
||||
"VID_DATA",
|
||||
"UNKNOWN_DATA",
|
||||
"CHUNK_DATA",
|
||||
"IKE_SPI",
|
||||
"ENCRYPTED_DATA",
|
||||
);
|
||||
|
|
|
@ -186,87 +186,6 @@ enum encoding_type_t {
|
|||
*/
|
||||
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.
|
||||
*
|
||||
|
@ -279,6 +198,7 @@ enum encoding_type_t {
|
|||
* is moved 1 bit forward afterwards.
|
||||
*/
|
||||
ATTRIBUTE_FORMAT,
|
||||
|
||||
/**
|
||||
* Representing a 15 Bit unsigned int value used as attribute type
|
||||
* in an attribute transform.
|
||||
|
@ -321,7 +241,7 @@ enum encoding_type_t {
|
|||
* The value is written to the associated data struct.
|
||||
* The current read pointer is moved 16 bit forward afterwards.
|
||||
*/
|
||||
CONFIGURATION_ATTRIBUTE_LENGTH,
|
||||
ATTRIBUTE_LENGTH,
|
||||
|
||||
/**
|
||||
* Depending on the field of type ATTRIBUTE_FORMAT
|
||||
|
@ -335,19 +255,6 @@ enum encoding_type_t {
|
|||
*/
|
||||
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.
|
||||
*
|
||||
|
@ -375,94 +282,9 @@ enum encoding_type_t {
|
|||
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.
|
||||
* Representing a variable length byte field.
|
||||
*/
|
||||
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_DATA,
|
||||
|
||||
/**
|
||||
* 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,
|
||||
CHUNK_DATA,
|
||||
|
||||
/**
|
||||
* Representating an IKE_SPI field in an IKEv2 Header.
|
||||
|
@ -475,9 +297,20 @@ enum encoding_type_t {
|
|||
IKE_SPI,
|
||||
|
||||
/**
|
||||
* Representing the encrypted data body of a encryption payload.
|
||||
* Representating an encrypted IKEv1 message.
|
||||
*/
|
||||
ENCRYPTED_DATA,
|
||||
|
||||
/**
|
||||
* Reprensenting a field containing a set of wrapped payloads.
|
||||
*
|
||||
* This type is not used directly, but as an offset to the wrapped payloads.
|
||||
* The type of the wrapped payload is added to this encoding type.
|
||||
*
|
||||
* @note As payload types are added to this encoding type, it has
|
||||
* to be the last in encoding_type_t.
|
||||
*/
|
||||
PAYLOAD_LIST = 1000 /* no comma, read above! */
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright (C) 2005-2010 Martin Willi
|
||||
* Copyright (C) 2010 revosec AG
|
||||
* Copyright (C) 2011 Tobias Brunner
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
|
@ -71,6 +72,11 @@ struct private_encryption_payload_t {
|
|||
* Contained payloads
|
||||
*/
|
||||
linked_list_t *payloads;
|
||||
|
||||
/**
|
||||
* Type of payload, ENCRYPTED or ENCRYPTED_V1
|
||||
*/
|
||||
payload_type_t type;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -79,7 +85,7 @@ struct private_encryption_payload_t {
|
|||
* The defined offsets are the positions in a object of type
|
||||
* private_encryption_payload_t.
|
||||
*/
|
||||
encoding_rule_t encryption_payload_encodings[] = {
|
||||
static encoding_rule_t encodings_v2[] = {
|
||||
/* 1 Byte next payload type, stored in the field next_payload */
|
||||
{ U_INT_8, offsetof(private_encryption_payload_t, next_payload) },
|
||||
/* Critical and 7 reserved bits, all stored for reconstruction */
|
||||
|
@ -87,7 +93,7 @@ encoding_rule_t encryption_payload_encodings[] = {
|
|||
/* 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) },
|
||||
{ CHUNK_DATA, offsetof(private_encryption_payload_t, encrypted) },
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -109,24 +115,59 @@ encoding_rule_t encryption_payload_encodings[] = {
|
|||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
/**
|
||||
* Encoding rules to parse or generate a complete encrypted IKEv1 message.
|
||||
*
|
||||
* The defined offsets are the positions in a object of type
|
||||
* private_encryption_payload_t.
|
||||
*/
|
||||
static encoding_rule_t encodings_v1[] = {
|
||||
/* encrypted data, stored in a chunk */
|
||||
{ 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
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! Encrypted IKE Payloads !
|
||||
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! ! Padding (0-255 octets) !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
METHOD(payload_t, verify, status_t,
|
||||
private_encryption_payload_t *this)
|
||||
{
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_encoding_rules, void,
|
||||
private_encryption_payload_t *this, encoding_rule_t **rules,
|
||||
size_t *count)
|
||||
METHOD(payload_t, get_encoding_rules, int,
|
||||
private_encryption_payload_t *this, encoding_rule_t **rules)
|
||||
{
|
||||
*rules = encryption_payload_encodings;
|
||||
*count = countof(encryption_payload_encodings);
|
||||
if (this->type == ENCRYPTED)
|
||||
{
|
||||
*rules = encodings_v2;
|
||||
return countof(encodings_v2);
|
||||
}
|
||||
*rules = encodings_v1;
|
||||
return countof(encodings_v1);
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_header_length, int,
|
||||
private_encryption_payload_t *this)
|
||||
{
|
||||
if (this->type == ENCRYPTED)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_type, payload_type_t,
|
||||
private_encryption_payload_t *this)
|
||||
{
|
||||
return ENCRYPTED;
|
||||
return this->type;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_next_type, payload_type_t,
|
||||
|
@ -138,7 +179,8 @@ METHOD(payload_t, get_next_type, payload_type_t,
|
|||
METHOD(payload_t, set_next_type, void,
|
||||
private_encryption_payload_t *this, payload_type_t type)
|
||||
{
|
||||
/* the next payload is set during add */
|
||||
/* the next payload is set during add, still allow this for IKEv1 */
|
||||
this->next_payload = type;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -174,7 +216,7 @@ static void compute_length(private_encryption_payload_t *this)
|
|||
length += this->aead->get_icv_size(this->aead);
|
||||
}
|
||||
}
|
||||
length += ENCRYPTION_PAYLOAD_HEADER_LENGTH;
|
||||
length += get_header_length(this);
|
||||
this->payload_length = length;
|
||||
}
|
||||
|
||||
|
@ -335,6 +377,47 @@ METHOD(encryption_payload_t, encrypt, bool,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(encryption_payload_t, encrypt_v1, bool,
|
||||
private_encryption_payload_t *this, chunk_t iv)
|
||||
{
|
||||
generator_t *generator;
|
||||
chunk_t plain, padding;
|
||||
size_t bs;
|
||||
|
||||
if (this->aead == NULL)
|
||||
{
|
||||
DBG1(DBG_ENC, "encryption failed, transform missing");
|
||||
chunk_free(&iv);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
generator = generator_create();
|
||||
plain = generate(this, generator);
|
||||
bs = this->aead->get_block_size(this->aead);
|
||||
padding.len = bs - (plain.len % bs);
|
||||
|
||||
/* prepare data to encrypt:
|
||||
* | plain | padding | */
|
||||
free(this->encrypted.ptr);
|
||||
this->encrypted = chunk_alloc(plain.len + padding.len);
|
||||
memcpy(this->encrypted.ptr, plain.ptr, plain.len);
|
||||
plain.ptr = this->encrypted.ptr;
|
||||
padding.ptr = plain.ptr + plain.len;
|
||||
memset(padding.ptr, 0, padding.len);
|
||||
generator->destroy(generator);
|
||||
|
||||
DBG3(DBG_ENC, "encrypting payloads:");
|
||||
DBG3(DBG_ENC, "plain %B", &plain);
|
||||
DBG3(DBG_ENC, "padding %B", &padding);
|
||||
|
||||
this->aead->encrypt(this->aead, this->encrypted, chunk_empty, iv, NULL);
|
||||
chunk_free(&iv);
|
||||
|
||||
DBG3(DBG_ENC, "encrypted %B", &this->encrypted);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the payloads after decryption.
|
||||
*/
|
||||
|
@ -349,6 +432,13 @@ static status_t parse(private_encryption_payload_t *this, chunk_t plain)
|
|||
{
|
||||
payload_t *payload;
|
||||
|
||||
if (plain.len < 4 || untoh16(plain.ptr + 2) > plain.len)
|
||||
{
|
||||
DBG1(DBG_ENC, "invalid %N payload length, decryption failed?",
|
||||
payload_type_names, type);
|
||||
parser->destroy(parser);
|
||||
return PARSE_ERROR;
|
||||
}
|
||||
if (parser->parse_payload(parser, type, &payload) != SUCCESS)
|
||||
{
|
||||
parser->destroy(parser);
|
||||
|
@ -438,6 +528,36 @@ METHOD(encryption_payload_t, decrypt, status_t,
|
|||
return parse(this, plain);
|
||||
}
|
||||
|
||||
METHOD(encryption_payload_t, decrypt_v1, status_t,
|
||||
private_encryption_payload_t *this, chunk_t iv)
|
||||
{
|
||||
if (this->aead == NULL)
|
||||
{
|
||||
DBG1(DBG_ENC, "decryption failed, transform missing");
|
||||
chunk_free(&iv);
|
||||
return INVALID_STATE;
|
||||
}
|
||||
|
||||
/* data must be a multiple of block size */
|
||||
if (iv.len != this->aead->get_block_size(this->aead) ||
|
||||
this->encrypted.len < iv.len || this->encrypted.len % iv.len)
|
||||
{
|
||||
DBG1(DBG_ENC, "decryption failed, invalid length");
|
||||
chunk_free(&iv);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
DBG3(DBG_ENC, "decrypting payloads:");
|
||||
DBG3(DBG_ENC, "encrypted %B", &this->encrypted);
|
||||
|
||||
this->aead->decrypt(this->aead, this->encrypted, chunk_empty, iv, NULL);
|
||||
chunk_free(&iv);
|
||||
|
||||
DBG3(DBG_ENC, "plain %B", &this->encrypted);
|
||||
|
||||
return parse(this, this->encrypted);
|
||||
}
|
||||
|
||||
METHOD(encryption_payload_t, set_transform, void,
|
||||
private_encryption_payload_t *this, aead_t* aead)
|
||||
{
|
||||
|
@ -455,7 +575,7 @@ METHOD2(payload_t, encryption_payload_t, destroy, void,
|
|||
/*
|
||||
* Described in header
|
||||
*/
|
||||
encryption_payload_t *encryption_payload_create()
|
||||
encryption_payload_t *encryption_payload_create(payload_type_t type)
|
||||
{
|
||||
private_encryption_payload_t *this;
|
||||
|
||||
|
@ -464,6 +584,7 @@ encryption_payload_t *encryption_payload_create()
|
|||
.payload_interface = {
|
||||
.verify = _verify,
|
||||
.get_encoding_rules = _get_encoding_rules,
|
||||
.get_header_length = _get_header_length,
|
||||
.get_length = _get_length,
|
||||
.get_next_type = _get_next_type,
|
||||
.set_next_type = _set_next_type,
|
||||
|
@ -479,9 +600,16 @@ encryption_payload_t *encryption_payload_create()
|
|||
.destroy = _destroy,
|
||||
},
|
||||
.next_payload = NO_PAYLOAD,
|
||||
.payload_length = ENCRYPTION_PAYLOAD_HEADER_LENGTH,
|
||||
.payload_length = get_header_length(this),
|
||||
.payloads = linked_list_create(),
|
||||
.type = type,
|
||||
);
|
||||
|
||||
if (type == ENCRYPTED_V1)
|
||||
{
|
||||
this->public.encrypt = _encrypt_v1;
|
||||
this->public.decrypt = _decrypt_v1;
|
||||
}
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
|
|
@ -29,11 +29,6 @@ typedef struct encryption_payload_t encryption_payload_t;
|
|||
#include <crypto/aead.h>
|
||||
#include <encoding/payloads/payload.h>
|
||||
|
||||
/**
|
||||
* Encrpytion payload length in bytes without IV and following data.
|
||||
*/
|
||||
#define ENCRYPTION_PAYLOAD_HEADER_LENGTH 4
|
||||
|
||||
/**
|
||||
* The encryption payload as described in RFC section 3.14.
|
||||
*/
|
||||
|
@ -102,8 +97,9 @@ struct encryption_payload_t {
|
|||
/**
|
||||
* Creates an empty encryption_payload_t object.
|
||||
*
|
||||
* @param type ENCRYPTED or ENCRYPTED_V1
|
||||
* @return encryption_payload_t object
|
||||
*/
|
||||
encryption_payload_t *encryption_payload_create(void);
|
||||
encryption_payload_t *encryption_payload_create(payload_type_t type);
|
||||
|
||||
#endif /** ENCRYPTION_PAYLOAD_H_ @}*/
|
||||
|
|
|
@ -227,7 +227,7 @@ METHOD(endpoint_notify_t, build_notify, notify_payload_t*,
|
|||
chunk_t data;
|
||||
notify_payload_t *notify;
|
||||
|
||||
notify = notify_payload_create();
|
||||
notify = notify_payload_create(NOTIFY);
|
||||
notify->set_notify_type(notify, ME_ENDPOINT);
|
||||
data = build_notification_data(this);
|
||||
notify->set_notification_data(notify, data);
|
||||
|
|
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
* Copyright (C) 2011 Martin Willi
|
||||
* Copyright (C) 2011 revosec AG
|
||||
*
|
||||
* 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 "hash_payload.h"
|
||||
|
||||
#include <encoding/payloads/encodings.h>
|
||||
|
||||
typedef struct private_hash_payload_t private_hash_payload_t;
|
||||
|
||||
/**
|
||||
* Private data of an hash_payload_t object.
|
||||
*/
|
||||
struct private_hash_payload_t {
|
||||
|
||||
/**
|
||||
* Public hash_payload_t interface.
|
||||
*/
|
||||
hash_payload_t public;
|
||||
|
||||
/**
|
||||
* Next payload type.
|
||||
*/
|
||||
u_int8_t next_payload;
|
||||
|
||||
/**
|
||||
* Reserved byte
|
||||
*/
|
||||
u_int8_t reserved;
|
||||
|
||||
/**
|
||||
* Length of this payload.
|
||||
*/
|
||||
u_int16_t payload_length;
|
||||
|
||||
/**
|
||||
* The contained hash value.
|
||||
*/
|
||||
chunk_t hash;
|
||||
|
||||
/**
|
||||
* either HASH_V1 or NAT_D_V1
|
||||
*/
|
||||
payload_type_t type;
|
||||
};
|
||||
|
||||
/**
|
||||
* Encoding rules for an IKEv1 hash payload
|
||||
*/
|
||||
static encoding_rule_t encodings[] = {
|
||||
/* 1 Byte next payload type, stored in the field next_payload */
|
||||
{ U_INT_8, offsetof(private_hash_payload_t, next_payload) },
|
||||
{ RESERVED_BYTE, offsetof(private_hash_payload_t, reserved) },
|
||||
/* Length of the whole payload*/
|
||||
{ PAYLOAD_LENGTH, offsetof(private_hash_payload_t, payload_length) },
|
||||
/* Hash Data is from variable size */
|
||||
{ CHUNK_DATA, offsetof(private_hash_payload_t, hash) },
|
||||
};
|
||||
|
||||
/*
|
||||
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 ! RESERVED ! Payload Length !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! !
|
||||
~ Hash Data ~
|
||||
! !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
METHOD(payload_t, verify, status_t,
|
||||
private_hash_payload_t *this)
|
||||
{
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_encoding_rules, int,
|
||||
private_hash_payload_t *this, encoding_rule_t **rules)
|
||||
{
|
||||
*rules = encodings;
|
||||
return countof(encodings);
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_header_length, int,
|
||||
private_hash_payload_t *this)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_type, payload_type_t,
|
||||
private_hash_payload_t *this)
|
||||
{
|
||||
return this->type;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_next_type, payload_type_t,
|
||||
private_hash_payload_t *this)
|
||||
{
|
||||
return this->next_payload;
|
||||
}
|
||||
|
||||
METHOD(payload_t, set_next_type, void,
|
||||
private_hash_payload_t *this, payload_type_t type)
|
||||
{
|
||||
this->next_payload = type;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_length, size_t,
|
||||
private_hash_payload_t *this)
|
||||
{
|
||||
return this->payload_length;
|
||||
}
|
||||
|
||||
METHOD(hash_payload_t, set_hash, void,
|
||||
private_hash_payload_t *this, chunk_t hash)
|
||||
{
|
||||
free(this->hash.ptr);
|
||||
this->hash = chunk_clone(hash);
|
||||
this->payload_length = get_header_length(this) + hash.len;
|
||||
}
|
||||
|
||||
METHOD(hash_payload_t, get_hash, chunk_t,
|
||||
private_hash_payload_t *this)
|
||||
{
|
||||
return this->hash;
|
||||
}
|
||||
|
||||
METHOD2(payload_t, hash_payload_t, destroy, void,
|
||||
private_hash_payload_t *this)
|
||||
{
|
||||
free(this->hash.ptr);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
hash_payload_t *hash_payload_create(payload_type_t type)
|
||||
{
|
||||
private_hash_payload_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.payload_interface = {
|
||||
.verify = _verify,
|
||||
.get_encoding_rules = _get_encoding_rules,
|
||||
.get_header_length = _get_header_length,
|
||||
.get_length = _get_length,
|
||||
.get_next_type = _get_next_type,
|
||||
.set_next_type = _set_next_type,
|
||||
.get_type = _get_type,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.set_hash = _set_hash,
|
||||
.get_hash = _get_hash,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.next_payload = NO_PAYLOAD,
|
||||
.payload_length = get_header_length(this),
|
||||
.type = type,
|
||||
);
|
||||
return &this->public;
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (C) 2011 Martin Willi
|
||||
* Copyright (C) 2011 revosec AG
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup hash_payload hash_payload
|
||||
* @{ @ingroup payloads
|
||||
*/
|
||||
|
||||
#ifndef HASH_PAYLOAD_H_
|
||||
#define HASH_PAYLOAD_H_
|
||||
|
||||
typedef struct hash_payload_t hash_payload_t;
|
||||
|
||||
#include <library.h>
|
||||
#include <encoding/payloads/payload.h>
|
||||
|
||||
/**
|
||||
* Object representing an IKEv1 hash payload.
|
||||
*/
|
||||
struct hash_payload_t {
|
||||
|
||||
/**
|
||||
* The payload_t interface.
|
||||
*/
|
||||
payload_t payload_interface;
|
||||
|
||||
/**
|
||||
* Set the hash value.
|
||||
*
|
||||
* @param hash chunk containing the hash, will be cloned
|
||||
*/
|
||||
void (*set_hash) (hash_payload_t *this, chunk_t hash);
|
||||
|
||||
/**
|
||||
* Get the hash value.
|
||||
*
|
||||
* @return chunkt to internal hash data
|
||||
*/
|
||||
chunk_t (*get_hash) (hash_payload_t *this);
|
||||
|
||||
/**
|
||||
* Destroys an hash_payload_t object.
|
||||
*/
|
||||
void (*destroy) (hash_payload_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates an empty hash_payload_t object.
|
||||
*
|
||||
* @param type either HASH_V1 or NAT_D_V1
|
||||
* @return hash_payload_t object
|
||||
*/
|
||||
hash_payload_t *hash_payload_create(payload_type_t type);
|
||||
|
||||
#endif /** HASH_PAYLOAD_H_ @}*/
|
|
@ -1,9 +1,8 @@
|
|||
/*
|
||||
* Copyright (C) 2005-2010 Martin Willi
|
||||
* Copyright (C) 2005-2011 Martin Willi
|
||||
* Copyright (C) 2010 revosec AG
|
||||
* Copyright (C) 2007 Tobias Brunner
|
||||
* Copyright (C) 2007-2011 Tobias Brunner
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
*
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
|
@ -28,19 +27,14 @@ 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;
|
||||
|
||||
/**
|
||||
* one of ID_INITIATOR, ID_RESPONDER
|
||||
*/
|
||||
payload_type_t payload_type;
|
||||
|
||||
/**
|
||||
* Next payload type.
|
||||
*/
|
||||
|
@ -75,19 +69,31 @@ struct private_id_payload_t {
|
|||
* The contained id data value.
|
||||
*/
|
||||
chunk_t id_data;
|
||||
|
||||
/**
|
||||
* Tunneled protocol ID for IKEv1 quick modes.
|
||||
*/
|
||||
u_int8_t protocol_id;
|
||||
|
||||
/**
|
||||
* Tunneled port for IKEv1 quick modes.
|
||||
*/
|
||||
u_int16_t port;
|
||||
|
||||
/**
|
||||
* one of ID_INITIATOR, ID_RESPONDER, IDv1 and NAT_OA_V1
|
||||
*/
|
||||
payload_type_t type;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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 rules for an IKEv2 ID payload
|
||||
*/
|
||||
encoding_rule_t id_payload_encodings[] = {
|
||||
static encoding_rule_t encodings_v2[] = {
|
||||
/* 1 Byte next payload type, stored in the field next_payload */
|
||||
{ U_INT_8, offsetof(private_id_payload_t, next_payload) },
|
||||
{ U_INT_8, offsetof(private_id_payload_t, next_payload) },
|
||||
/* the critical bit */
|
||||
{ FLAG, offsetof(private_id_payload_t, critical) },
|
||||
{ FLAG, offsetof(private_id_payload_t, critical) },
|
||||
/* 7 Bit reserved bits */
|
||||
{ RESERVED_BIT, offsetof(private_id_payload_t, reserved_bit[0]) },
|
||||
{ RESERVED_BIT, offsetof(private_id_payload_t, reserved_bit[1]) },
|
||||
|
@ -97,7 +103,7 @@ encoding_rule_t id_payload_encodings[] = {
|
|||
{ RESERVED_BIT, offsetof(private_id_payload_t, reserved_bit[5]) },
|
||||
{ RESERVED_BIT, offsetof(private_id_payload_t, reserved_bit[6]) },
|
||||
/* Length of the whole payload*/
|
||||
{ PAYLOAD_LENGTH, offsetof(private_id_payload_t, payload_length) },
|
||||
{ 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 */
|
||||
|
@ -105,7 +111,7 @@ encoding_rule_t id_payload_encodings[] = {
|
|||
{ RESERVED_BYTE, offsetof(private_id_payload_t, reserved_byte[1])},
|
||||
{ RESERVED_BYTE, offsetof(private_id_payload_t, reserved_byte[2])},
|
||||
/* some id data bytes, length is defined in PAYLOAD_LENGTH */
|
||||
{ ID_DATA, offsetof(private_id_payload_t, id_data) }
|
||||
{ CHUNK_DATA, offsetof(private_id_payload_t, id_data) },
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -122,29 +128,92 @@ encoding_rule_t id_payload_encodings[] = {
|
|||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
/**
|
||||
* Encoding rules for an IKEv1 ID payload
|
||||
*/
|
||||
static encoding_rule_t encodings_v1[] = {
|
||||
/* 1 Byte next payload type, stored in the field next_payload */
|
||||
{ U_INT_8, offsetof(private_id_payload_t, next_payload) },
|
||||
/* Reserved Byte is skipped */
|
||||
{ RESERVED_BYTE, offsetof(private_id_payload_t, reserved_byte[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) },
|
||||
{ U_INT_8, offsetof(private_id_payload_t, protocol_id) },
|
||||
{ U_INT_16, offsetof(private_id_payload_t, port) },
|
||||
/* some id data bytes, length is defined in PAYLOAD_LENGTH */
|
||||
{ CHUNK_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 ! RESERVED ! Payload Length !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! ID Type ! Protocol ID ! Port |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! !
|
||||
~ Identification Data ~
|
||||
! !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
METHOD(payload_t, verify, status_t,
|
||||
private_id_payload_t *this)
|
||||
{
|
||||
if (this->id_type == 0 || this->id_type == 4)
|
||||
bool bad_length = FALSE;
|
||||
|
||||
if (this->type == NAT_OA_V1 &&
|
||||
this->id_type != ID_IPV4_ADDR && this->id_type != ID_IPV6_ADDR)
|
||||
{
|
||||
/* reserved IDs */
|
||||
DBG1(DBG_ENC, "received ID with reserved type %d", this->id_type);
|
||||
DBG1(DBG_ENC, "invalid ID type %N for %N payload", id_type_names,
|
||||
this->id_type, payload_type_short_names, this->type);
|
||||
return FAILED;
|
||||
}
|
||||
switch (this->id_type)
|
||||
{
|
||||
case ID_IPV4_ADDR_RANGE:
|
||||
case ID_IPV4_ADDR_SUBNET:
|
||||
bad_length = this->id_data.len != 8;
|
||||
break;
|
||||
case ID_IPV6_ADDR_RANGE:
|
||||
case ID_IPV6_ADDR_SUBNET:
|
||||
bad_length = this->id_data.len != 32;
|
||||
break;
|
||||
}
|
||||
if (bad_length)
|
||||
{
|
||||
DBG1(DBG_ENC, "invalid %N length (%d bytes)",
|
||||
id_type_names, this->id_type, this->id_data.len);
|
||||
return FAILED;
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_encoding_rules, void,
|
||||
private_id_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
|
||||
METHOD(payload_t, get_encoding_rules, int,
|
||||
private_id_payload_t *this, encoding_rule_t **rules)
|
||||
{
|
||||
*rules = id_payload_encodings;
|
||||
*rule_count = countof(id_payload_encodings);
|
||||
if (this->type == ID_V1 || this->type == NAT_OA_V1)
|
||||
{
|
||||
*rules = encodings_v1;
|
||||
return countof(encodings_v1);
|
||||
}
|
||||
*rules = encodings_v2;
|
||||
return countof(encodings_v2);
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_header_length, int,
|
||||
private_id_payload_t *this)
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_type, payload_type_t,
|
||||
private_id_payload_t *this)
|
||||
{
|
||||
return this->payload_type;
|
||||
return this->type;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_next_type, payload_type_t,
|
||||
|
@ -171,6 +240,102 @@ METHOD(id_payload_t, get_identification, identification_t*,
|
|||
return identification_create_from_encoding(this->id_type, this->id_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a traffic selector from an range ID
|
||||
*/
|
||||
static traffic_selector_t *get_ts_from_range(private_id_payload_t *this,
|
||||
ts_type_t type)
|
||||
{
|
||||
return traffic_selector_create_from_bytes(this->protocol_id, type,
|
||||
chunk_create(this->id_data.ptr, this->id_data.len / 2), this->port,
|
||||
chunk_skip(this->id_data, this->id_data.len / 2), this->port ?: 65535);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a traffic selector from an subnet ID
|
||||
*/
|
||||
static traffic_selector_t *get_ts_from_subnet(private_id_payload_t *this,
|
||||
ts_type_t type)
|
||||
{
|
||||
chunk_t net, netmask;
|
||||
int i;
|
||||
|
||||
net = chunk_create(this->id_data.ptr, this->id_data.len / 2);
|
||||
netmask = chunk_skip(this->id_data, this->id_data.len / 2);
|
||||
for (i = 0; i < net.len; i++)
|
||||
{
|
||||
netmask.ptr[i] = (netmask.ptr[i] ^ 0xFF) | net.ptr[i];
|
||||
}
|
||||
return traffic_selector_create_from_bytes(this->protocol_id, type,
|
||||
net, this->port, netmask, this->port ?: 65535);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a traffic selector from an IP ID
|
||||
*/
|
||||
static traffic_selector_t *get_ts_from_ip(private_id_payload_t *this,
|
||||
ts_type_t type)
|
||||
{
|
||||
return traffic_selector_create_from_bytes(this->protocol_id, type,
|
||||
this->id_data, this->port, this->id_data, this->port ?: 65535);
|
||||
}
|
||||
|
||||
METHOD(id_payload_t, get_ts, traffic_selector_t*,
|
||||
private_id_payload_t *this)
|
||||
{
|
||||
switch (this->id_type)
|
||||
{
|
||||
case ID_IPV4_ADDR_SUBNET:
|
||||
if (this->id_data.len == 8)
|
||||
{
|
||||
return get_ts_from_subnet(this, TS_IPV4_ADDR_RANGE);
|
||||
}
|
||||
break;
|
||||
case ID_IPV6_ADDR_SUBNET:
|
||||
if (this->id_data.len == 32)
|
||||
{
|
||||
return get_ts_from_subnet(this, TS_IPV6_ADDR_RANGE);
|
||||
}
|
||||
break;
|
||||
case ID_IPV4_ADDR_RANGE:
|
||||
if (this->id_data.len == 8)
|
||||
{
|
||||
return get_ts_from_range(this, TS_IPV4_ADDR_RANGE);
|
||||
}
|
||||
break;
|
||||
case ID_IPV6_ADDR_RANGE:
|
||||
if (this->id_data.len == 32)
|
||||
{
|
||||
return get_ts_from_range(this, TS_IPV6_ADDR_RANGE);
|
||||
}
|
||||
break;
|
||||
case ID_IPV4_ADDR:
|
||||
if (this->id_data.len == 4)
|
||||
{
|
||||
return get_ts_from_ip(this, TS_IPV4_ADDR_RANGE);
|
||||
}
|
||||
break;
|
||||
case ID_IPV6_ADDR:
|
||||
if (this->id_data.len == 16)
|
||||
{
|
||||
return get_ts_from_ip(this, TS_IPV6_ADDR_RANGE);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
METHOD(id_payload_t, get_encoded, chunk_t,
|
||||
private_id_payload_t *this)
|
||||
{
|
||||
u_int16_t port = htons(this->port);
|
||||
return chunk_cat("cccc", chunk_from_thing(this->id_type),
|
||||
chunk_from_thing(this->protocol_id),
|
||||
chunk_from_thing(port), this->id_data);
|
||||
}
|
||||
|
||||
METHOD2(payload_t, id_payload_t, destroy, void,
|
||||
private_id_payload_t *this)
|
||||
{
|
||||
|
@ -181,7 +346,7 @@ METHOD2(payload_t, id_payload_t, destroy, void,
|
|||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
id_payload_t *id_payload_create(payload_type_t payload_type)
|
||||
id_payload_t *id_payload_create(payload_type_t type)
|
||||
{
|
||||
private_id_payload_t *this;
|
||||
|
||||
|
@ -190,6 +355,7 @@ id_payload_t *id_payload_create(payload_type_t payload_type)
|
|||
.payload_interface = {
|
||||
.verify = _verify,
|
||||
.get_encoding_rules = _get_encoding_rules,
|
||||
.get_header_length = _get_header_length,
|
||||
.get_length = _get_length,
|
||||
.get_next_type = _get_next_type,
|
||||
.set_next_type = _set_next_type,
|
||||
|
@ -197,11 +363,13 @@ id_payload_t *id_payload_create(payload_type_t payload_type)
|
|||
.destroy = _destroy,
|
||||
},
|
||||
.get_identification = _get_identification,
|
||||
.get_encoded = _get_encoded,
|
||||
.get_ts = _get_ts,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.next_payload = NO_PAYLOAD,
|
||||
.payload_length = ID_PAYLOAD_HEADER_LENGTH,
|
||||
.payload_type = payload_type,
|
||||
.payload_length = get_header_length(this),
|
||||
.type = type,
|
||||
);
|
||||
return &this->public;
|
||||
}
|
||||
|
@ -209,15 +377,89 @@ id_payload_t *id_payload_create(payload_type_t payload_type)
|
|||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
id_payload_t *id_payload_create_from_identification(payload_type_t payload_type,
|
||||
id_payload_t *id_payload_create_from_identification(payload_type_t type,
|
||||
identification_t *id)
|
||||
{
|
||||
private_id_payload_t *this;
|
||||
|
||||
this = (private_id_payload_t*)id_payload_create(payload_type);
|
||||
this = (private_id_payload_t*)id_payload_create(type);
|
||||
this->id_data = chunk_clone(id->get_encoding(id));
|
||||
this->id_type = id->get_type(id);
|
||||
this->payload_length += this->id_data.len;
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
id_payload_t *id_payload_create_from_ts(traffic_selector_t *ts)
|
||||
{
|
||||
private_id_payload_t *this;
|
||||
u_int8_t mask;
|
||||
host_t *net;
|
||||
|
||||
this = (private_id_payload_t*)id_payload_create(ID_V1);
|
||||
|
||||
if (ts->is_host(ts, NULL))
|
||||
{
|
||||
if (ts->get_type(ts) == TS_IPV4_ADDR_RANGE)
|
||||
{
|
||||
this->id_type = ID_IPV4_ADDR;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->id_type = ID_IPV6_ADDR;
|
||||
}
|
||||
this->id_data = chunk_clone(ts->get_from_address(ts));
|
||||
}
|
||||
else if (ts->to_subnet(ts, &net, &mask))
|
||||
{
|
||||
u_int8_t netmask[16], len, byte;
|
||||
|
||||
if (ts->get_type(ts) == TS_IPV4_ADDR_RANGE)
|
||||
{
|
||||
this->id_type = ID_IPV4_ADDR_SUBNET;
|
||||
len = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->id_type = ID_IPV6_ADDR_SUBNET;
|
||||
len = 16;
|
||||
}
|
||||
memset(netmask, 0, sizeof(netmask));
|
||||
for (byte = 0; byte < sizeof(netmask); byte++)
|
||||
{
|
||||
if (mask < 8)
|
||||
{
|
||||
netmask[byte] = 0xFF << (8 - mask);
|
||||
break;
|
||||
}
|
||||
netmask[byte] = 0xFF;
|
||||
mask -= 8;
|
||||
}
|
||||
this->id_data = chunk_cat("cc", net->get_address(net),
|
||||
chunk_create(netmask, len));
|
||||
net->destroy(net);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ts->get_type(ts) == TS_IPV4_ADDR_RANGE)
|
||||
{
|
||||
this->id_type = ID_IPV4_ADDR_RANGE;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->id_type = ID_IPV6_ADDR_RANGE;
|
||||
}
|
||||
this->id_data = chunk_cat("cc",
|
||||
ts->get_from_address(ts), ts->get_to_address(ts));
|
||||
net->destroy(net);
|
||||
}
|
||||
this->port = ts->get_from_port(ts);
|
||||
this->protocol_id = ts->get_protocol(ts);
|
||||
this->payload_length += this->id_data.len;
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,16 +28,10 @@ typedef struct id_payload_t id_payload_t;
|
|||
#include <library.h>
|
||||
#include <utils/identification.h>
|
||||
#include <encoding/payloads/payload.h>
|
||||
#include <selectors/traffic_selector.h>
|
||||
|
||||
/**
|
||||
* Length of a id payload without the data in bytes.
|
||||
*/
|
||||
#define ID_PAYLOAD_HEADER_LENGTH 8
|
||||
|
||||
/**
|
||||
* Object representing an IKEv2 ID payload.
|
||||
*
|
||||
* The ID payload format is described in RFC section 3.5.
|
||||
* Object representing an IKEv1 or an IKEv2 ID payload.
|
||||
*/
|
||||
struct id_payload_t {
|
||||
|
||||
|
@ -53,6 +47,20 @@ struct id_payload_t {
|
|||
*/
|
||||
identification_t *(*get_identification) (id_payload_t *this);
|
||||
|
||||
/**
|
||||
* Creates a traffic selector form a ID_ADDR_SUBNET/RANGE identity.
|
||||
*
|
||||
* @return traffic selector, NULL on failure
|
||||
*/
|
||||
traffic_selector_t* (*get_ts)(id_payload_t *this);
|
||||
|
||||
/**
|
||||
* Get encoded payload without fixed payload header (used for IKEv1).
|
||||
*
|
||||
* @return encoded payload (gets allocated)
|
||||
*/
|
||||
chunk_t (*get_encoded)(id_payload_t *this);
|
||||
|
||||
/**
|
||||
* Destroys an id_payload_t object.
|
||||
*/
|
||||
|
@ -62,19 +70,27 @@ struct id_payload_t {
|
|||
/**
|
||||
* Creates an empty id_payload_t object.
|
||||
*
|
||||
* @param payload_type one of ID_INITIATOR, ID_RESPONDER
|
||||
* @return id_payload_t object
|
||||
* @param type one of ID_INITIATOR, ID_RESPONDER, ID_V1 and NAT_OA_V1
|
||||
* @return id_payload_t object
|
||||
*/
|
||||
id_payload_t *id_payload_create(payload_type_t payload_type);
|
||||
id_payload_t *id_payload_create(payload_type_t type);
|
||||
|
||||
/**
|
||||
* Creates an id_payload_t from an existing identification_t object.
|
||||
*
|
||||
* @param payload_type one of ID_INITIATOR, ID_RESPONDER
|
||||
* @param identification identification_t object
|
||||
* @return id_payload_t object
|
||||
* @param type one of ID_INITIATOR, ID_RESPONDER, ID_V1 and NAT_OA_V1
|
||||
* @param id identification_t object
|
||||
* @return id_payload_t object
|
||||
*/
|
||||
id_payload_t *id_payload_create_from_identification(payload_type_t payload_type,
|
||||
identification_t *identification);
|
||||
id_payload_t *id_payload_create_from_identification(payload_type_t type,
|
||||
identification_t *id);
|
||||
|
||||
/**
|
||||
* Create an IKEv1 ID_ADDR_SUBNET/RANGE identity from a traffic selector.
|
||||
*
|
||||
* @param ts traffic selector
|
||||
* @return ID_V1 id_paylad_t object.
|
||||
*/
|
||||
id_payload_t *id_payload_create_from_ts(traffic_selector_t *ts);
|
||||
|
||||
#endif /** ID_PAYLOAD_H_ @}*/
|
||||
|
|
|
@ -81,12 +81,27 @@ struct private_ike_header_t {
|
|||
* TRUE, if this is a response, FALSE if its a Request.
|
||||
*/
|
||||
bool response;
|
||||
|
||||
/**
|
||||
* TRUE, if the packet is encrypted (IKEv1).
|
||||
*/
|
||||
bool encryption;
|
||||
|
||||
/**
|
||||
* TRUE, if the commit flag is set (IKEv1).
|
||||
*/
|
||||
bool commit;
|
||||
|
||||
/**
|
||||
* TRUE, if the auth only flag is set (IKEv1).
|
||||
*/
|
||||
bool authonly;
|
||||
} flags;
|
||||
|
||||
/**
|
||||
* Reserved bits of IKE header
|
||||
*/
|
||||
bool reserved[5];
|
||||
bool reserved[2];
|
||||
|
||||
/**
|
||||
* Associated Message-ID.
|
||||
|
@ -99,9 +114,15 @@ struct private_ike_header_t {
|
|||
u_int32_t length;
|
||||
};
|
||||
|
||||
ENUM_BEGIN(exchange_type_names, EXCHANGE_TYPE_UNDEFINED, EXCHANGE_TYPE_UNDEFINED,
|
||||
"EXCHANGE_TYPE_UNDEFINED");
|
||||
ENUM_NEXT(exchange_type_names, IKE_SA_INIT, IKE_SESSION_RESUME, EXCHANGE_TYPE_UNDEFINED,
|
||||
ENUM_BEGIN(exchange_type_names, ID_PROT, TRANSACTION,
|
||||
"ID_PROT",
|
||||
"AUTH_ONLY",
|
||||
"AGGRESSIVE",
|
||||
"INFORMATIONAL_V1",
|
||||
"TRANSACTION");
|
||||
ENUM_NEXT(exchange_type_names, QUICK_MODE, IKE_SESSION_RESUME, TRANSACTION,
|
||||
"QUICK_MODE",
|
||||
"NEW_GROUP_MODE",
|
||||
"IKE_SA_INIT",
|
||||
"IKE_AUTH",
|
||||
"CREATE_CHILD_SA",
|
||||
|
@ -110,18 +131,23 @@ ENUM_NEXT(exchange_type_names, IKE_SA_INIT, IKE_SESSION_RESUME, EXCHANGE_TYPE_UN
|
|||
#ifdef ME
|
||||
ENUM_NEXT(exchange_type_names, ME_CONNECT, ME_CONNECT, IKE_SESSION_RESUME,
|
||||
"ME_CONNECT");
|
||||
ENUM_END(exchange_type_names, ME_CONNECT);
|
||||
ENUM_NEXT(exchange_type_names, EXCHANGE_TYPE_UNDEFINED,
|
||||
EXCHANGE_TYPE_UNDEFINED, ME_CONNECT,
|
||||
"EXCHANGE_TYPE_UNDEFINED");
|
||||
#else
|
||||
ENUM_END(exchange_type_names, IKE_SESSION_RESUME);
|
||||
ENUM_NEXT(exchange_type_names, EXCHANGE_TYPE_UNDEFINED,
|
||||
EXCHANGE_TYPE_UNDEFINED, IKE_SESSION_RESUME,
|
||||
"EXCHANGE_TYPE_UNDEFINED");
|
||||
#endif /* ME */
|
||||
ENUM_END(exchange_type_names, EXCHANGE_TYPE_UNDEFINED);
|
||||
|
||||
/**
|
||||
* Encoding rules to parse or generate a IKEv2-Header.
|
||||
* Encoding rules to parse or generate a IKE-Header.
|
||||
*
|
||||
* The defined offsets are the positions in a object of type
|
||||
* ike_header_t.
|
||||
*/
|
||||
encoding_rule_t ike_header_encodings[] = {
|
||||
static encoding_rule_t 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 */
|
||||
|
@ -137,22 +163,20 @@ encoding_rule_t ike_header_encodings[] = {
|
|||
/* 2 Bit reserved bits */
|
||||
{ RESERVED_BIT, offsetof(private_ike_header_t, reserved[0]) },
|
||||
{ RESERVED_BIT, offsetof(private_ike_header_t, reserved[1]) },
|
||||
/* 3 Bit flags, stored in the fields response, version and initiator */
|
||||
/* 6 flags */
|
||||
{ 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 */
|
||||
{ RESERVED_BIT, offsetof(private_ike_header_t, reserved[2]) },
|
||||
{ RESERVED_BIT, offsetof(private_ike_header_t, reserved[3]) },
|
||||
{ RESERVED_BIT, offsetof(private_ike_header_t, reserved[4]) },
|
||||
{ FLAG, offsetof(private_ike_header_t, flags.authonly) },
|
||||
{ FLAG, offsetof(private_ike_header_t, flags.commit) },
|
||||
{ FLAG, offsetof(private_ike_header_t, flags.encryption)},
|
||||
/* 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) },
|
||||
{ HEADER_LENGTH, offsetof(private_ike_header_t, length) }
|
||||
};
|
||||
|
||||
|
||||
/* 1 2 3
|
||||
/* 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 !
|
||||
|
@ -172,35 +196,67 @@ encoding_rule_t ike_header_encodings[] = {
|
|||
METHOD(payload_t, verify, status_t,
|
||||
private_ike_header_t *this)
|
||||
{
|
||||
if ((this->exchange_type < IKE_SA_INIT) ||
|
||||
((this->exchange_type > INFORMATIONAL)
|
||||
#ifdef ME
|
||||
&& (this->exchange_type != ME_CONNECT)
|
||||
#endif /* ME */
|
||||
))
|
||||
switch (this->exchange_type)
|
||||
{
|
||||
/* unsupported exchange type */
|
||||
return FAILED;
|
||||
case ID_PROT:
|
||||
case AGGRESSIVE:
|
||||
if (this->message_id != 0)
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
/* fall */
|
||||
case AUTH_ONLY:
|
||||
case INFORMATIONAL_V1:
|
||||
case TRANSACTION:
|
||||
case QUICK_MODE:
|
||||
case NEW_GROUP_MODE:
|
||||
if (this->maj_version != IKEV1_MAJOR_VERSION)
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
break;
|
||||
case IKE_SA_INIT:
|
||||
case IKE_AUTH:
|
||||
case CREATE_CHILD_SA:
|
||||
case INFORMATIONAL:
|
||||
case IKE_SESSION_RESUME:
|
||||
#ifdef ME
|
||||
case ME_CONNECT:
|
||||
#endif /* ME */
|
||||
if (this->maj_version != IKEV2_MAJOR_VERSION)
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* unsupported exchange type */
|
||||
return FAILED;
|
||||
}
|
||||
if (this->initiator_spi == 0
|
||||
#ifdef ME
|
||||
/* we allow zero spi for INFORMATIONAL exchanges,
|
||||
* to allow connectivity checks */
|
||||
&& this->exchange_type != INFORMATIONAL
|
||||
#endif /* ME */
|
||||
)
|
||||
if (this->initiator_spi == 0)
|
||||
{
|
||||
/* initiator spi not set */
|
||||
return FAILED;
|
||||
#ifdef ME
|
||||
if (this->exchange_type != INFORMATIONAL)
|
||||
/* we allow zero spi for INFORMATIONAL exchanges,
|
||||
* to allow connectivity checks */
|
||||
#endif /* ME */
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_encoding_rules, void,
|
||||
private_ike_header_t *this, encoding_rule_t **rules, size_t *rule_count)
|
||||
METHOD(payload_t, get_encoding_rules, int,
|
||||
private_ike_header_t *this, encoding_rule_t **rules)
|
||||
{
|
||||
*rules = ike_header_encodings;
|
||||
*rule_count = sizeof(ike_header_encodings) / sizeof(encoding_rule_t);
|
||||
*rules = encodings;
|
||||
return countof(encodings);
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_header_length, int,
|
||||
private_ike_header_t *this)
|
||||
{
|
||||
return IKE_HEADER_LENGTH;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_type, payload_type_t,
|
||||
|
@ -311,6 +367,43 @@ METHOD(ike_header_t, set_initiator_flag, void,
|
|||
this->flags.initiator = initiator;
|
||||
}
|
||||
|
||||
METHOD(ike_header_t, get_encryption_flag, bool,
|
||||
private_ike_header_t *this)
|
||||
{
|
||||
return this->flags.encryption;
|
||||
}
|
||||
|
||||
METHOD(ike_header_t, set_encryption_flag, void,
|
||||
private_ike_header_t *this, bool encryption)
|
||||
{
|
||||
this->flags.encryption = encryption;
|
||||
}
|
||||
|
||||
|
||||
METHOD(ike_header_t, get_commit_flag, bool,
|
||||
private_ike_header_t *this)
|
||||
{
|
||||
return this->flags.commit;
|
||||
}
|
||||
|
||||
METHOD(ike_header_t, set_commit_flag, void,
|
||||
private_ike_header_t *this, bool commit)
|
||||
{
|
||||
this->flags.commit = commit;
|
||||
}
|
||||
|
||||
METHOD(ike_header_t, get_authonly_flag, bool,
|
||||
private_ike_header_t *this)
|
||||
{
|
||||
return this->flags.authonly;
|
||||
}
|
||||
|
||||
METHOD(ike_header_t, set_authonly_flag, void,
|
||||
private_ike_header_t *this, bool authonly)
|
||||
{
|
||||
this->flags.authonly = authonly;
|
||||
}
|
||||
|
||||
METHOD(ike_header_t, get_exchange_type, u_int8_t,
|
||||
private_ike_header_t *this)
|
||||
{
|
||||
|
@ -353,6 +446,7 @@ ike_header_t *ike_header_create()
|
|||
.payload_interface = {
|
||||
.verify = _verify,
|
||||
.get_encoding_rules = _get_encoding_rules,
|
||||
.get_header_length = _get_header_length,
|
||||
.get_length = _get_length,
|
||||
.get_next_type = _get_next_type,
|
||||
.set_next_type = _set_next_type,
|
||||
|
@ -373,21 +467,38 @@ ike_header_t *ike_header_create()
|
|||
.set_version_flag = _set_version_flag,
|
||||
.get_initiator_flag = _get_initiator_flag,
|
||||
.set_initiator_flag = _set_initiator_flag,
|
||||
.get_encryption_flag = _get_encryption_flag,
|
||||
.set_encryption_flag = _set_encryption_flag,
|
||||
.get_commit_flag = _get_commit_flag,
|
||||
.set_commit_flag = _set_commit_flag,
|
||||
.get_authonly_flag = _get_authonly_flag,
|
||||
.set_authonly_flag = _set_authonly_flag,
|
||||
.get_exchange_type = _get_exchange_type,
|
||||
.set_exchange_type = _set_exchange_type,
|
||||
.get_message_id = _get_message_id,
|
||||
.set_message_id = _set_message_id,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.maj_version = IKE_MAJOR_VERSION,
|
||||
.min_version = IKE_MINOR_VERSION,
|
||||
.exchange_type = EXCHANGE_TYPE_UNDEFINED,
|
||||
.flags = {
|
||||
.initiator = TRUE,
|
||||
.version = HIGHER_VERSION_SUPPORTED_FLAG,
|
||||
},
|
||||
.length = IKE_HEADER_LENGTH,
|
||||
.exchange_type = EXCHANGE_TYPE_UNDEFINED,
|
||||
);
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
ike_header_t *ike_header_create_version(int major, int minor)
|
||||
{
|
||||
ike_header_t *this = ike_header_create();
|
||||
|
||||
this->set_maj_version(this, major);
|
||||
this->set_min_version(this, minor);
|
||||
if (major == IKEV2_MAJOR_VERSION)
|
||||
{
|
||||
this->set_initiator_flag(this, TRUE);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (C) 2007 Tobias Brunner
|
||||
* Copyright (C) 2005-2006 Martin Willi
|
||||
* Copyright (C) 2005-2011 Martin Willi
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
|
@ -30,19 +30,24 @@ typedef struct ike_header_t ike_header_t;
|
|||
#include <encoding/payloads/payload.h>
|
||||
|
||||
/**
|
||||
* Major Version of IKEv2.
|
||||
* Major Version of IKEv1 we implement.
|
||||
*/
|
||||
#define IKE_MAJOR_VERSION 2
|
||||
#define IKEV1_MAJOR_VERSION 1
|
||||
|
||||
/**
|
||||
* Minor Version of IKEv2.
|
||||
* Minor Version of IKEv1 we implement.
|
||||
*/
|
||||
#define IKE_MINOR_VERSION 0
|
||||
#define IKEV1_MINOR_VERSION 0
|
||||
|
||||
/**
|
||||
* Flag in IKEv2-Header. Always 0.
|
||||
* Major Version of IKEv2 we implement.
|
||||
*/
|
||||
#define HIGHER_VERSION_SUPPORTED_FLAG 0
|
||||
#define IKEV2_MAJOR_VERSION 2
|
||||
|
||||
/**
|
||||
* Minor Version of IKEv2 we implement.
|
||||
*/
|
||||
#define IKEV2_MINOR_VERSION 0
|
||||
|
||||
/**
|
||||
* Length of IKE Header in Bytes.
|
||||
|
@ -57,9 +62,39 @@ typedef struct ike_header_t ike_header_t;
|
|||
enum exchange_type_t{
|
||||
|
||||
/**
|
||||
* EXCHANGE_TYPE_UNDEFINED. In private space, since not a official message type.
|
||||
* Identity Protection (Main mode).
|
||||
*/
|
||||
EXCHANGE_TYPE_UNDEFINED = 255,
|
||||
ID_PROT = 2,
|
||||
|
||||
/**
|
||||
* Authentication Only.
|
||||
*/
|
||||
AUTH_ONLY = 3,
|
||||
|
||||
/**
|
||||
* Aggresive (Aggressive mode)
|
||||
*/
|
||||
AGGRESSIVE = 4,
|
||||
|
||||
/**
|
||||
* Informational in IKEv1
|
||||
*/
|
||||
INFORMATIONAL_V1 = 5,
|
||||
|
||||
/**
|
||||
* Transaction (ISAKMP Cfg Mode "draft-ietf-ipsec-isakmp-mode-cfg-05")
|
||||
*/
|
||||
TRANSACTION = 6,
|
||||
|
||||
/**
|
||||
* Quick Mode
|
||||
*/
|
||||
QUICK_MODE = 32,
|
||||
|
||||
/**
|
||||
* New Group Mode
|
||||
*/
|
||||
NEW_GROUP_MODE = 33,
|
||||
|
||||
/**
|
||||
* IKE_SA_INIT.
|
||||
|
@ -77,7 +112,7 @@ enum exchange_type_t{
|
|||
CREATE_CHILD_SA = 36,
|
||||
|
||||
/**
|
||||
* INFORMATIONAL.
|
||||
* INFORMATIONAL in IKEv2.
|
||||
*/
|
||||
INFORMATIONAL = 37,
|
||||
|
||||
|
@ -85,12 +120,18 @@ enum exchange_type_t{
|
|||
* IKE_SESSION_RESUME (RFC 5723).
|
||||
*/
|
||||
IKE_SESSION_RESUME = 38,
|
||||
|
||||
#ifdef ME
|
||||
/**
|
||||
* ME_CONNECT
|
||||
*/
|
||||
ME_CONNECT = 240
|
||||
ME_CONNECT = 240,
|
||||
#endif /* ME */
|
||||
|
||||
/**
|
||||
* Undefined exchange type, in private space.
|
||||
*/
|
||||
EXCHANGE_TYPE_UNDEFINED = 255,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -99,12 +140,7 @@ enum exchange_type_t{
|
|||
extern enum_name_t *exchange_type_names;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* An object of this type represents an IKE header of either IKEv1 or IKEv2.
|
||||
*/
|
||||
struct ike_header_t {
|
||||
/**
|
||||
|
@ -115,7 +151,7 @@ struct ike_header_t {
|
|||
/**
|
||||
* Get the initiator spi.
|
||||
*
|
||||
* @return initiator_spi
|
||||
* @return initiator_spi
|
||||
*/
|
||||
u_int64_t (*get_initiator_spi) (ike_header_t *this);
|
||||
|
||||
|
@ -129,7 +165,7 @@ struct ike_header_t {
|
|||
/**
|
||||
* Get the responder spi.
|
||||
*
|
||||
* @return responder_spi
|
||||
* @return responder_spi
|
||||
*/
|
||||
u_int64_t (*get_responder_spi) (ike_header_t *this);
|
||||
|
||||
|
@ -143,7 +179,7 @@ struct ike_header_t {
|
|||
/**
|
||||
* Get the major version.
|
||||
*
|
||||
* @return major version
|
||||
* @return major version
|
||||
*/
|
||||
u_int8_t (*get_maj_version) (ike_header_t *this);
|
||||
|
||||
|
@ -157,7 +193,7 @@ struct ike_header_t {
|
|||
/**
|
||||
* Get the minor version.
|
||||
*
|
||||
* @return minor version
|
||||
* @return minor version
|
||||
*/
|
||||
u_int8_t (*get_min_version) (ike_header_t *this);
|
||||
|
||||
|
@ -171,7 +207,7 @@ struct ike_header_t {
|
|||
/**
|
||||
* Get the response flag.
|
||||
*
|
||||
* @return response flag
|
||||
* @return response flag
|
||||
*/
|
||||
bool (*get_response_flag) (ike_header_t *this);
|
||||
|
||||
|
@ -185,7 +221,7 @@ struct ike_header_t {
|
|||
/**
|
||||
* Get "higher version supported"-flag.
|
||||
*
|
||||
* @return version flag
|
||||
* @return version flag
|
||||
*/
|
||||
bool (*get_version_flag) (ike_header_t *this);
|
||||
|
||||
|
@ -199,7 +235,7 @@ struct ike_header_t {
|
|||
/**
|
||||
* Get the initiator flag.
|
||||
*
|
||||
* @return initiator flag
|
||||
* @return initiator flag
|
||||
*/
|
||||
bool (*get_initiator_flag) (ike_header_t *this);
|
||||
|
||||
|
@ -210,10 +246,52 @@ struct ike_header_t {
|
|||
*/
|
||||
void (*set_initiator_flag) (ike_header_t *this, bool initiator);
|
||||
|
||||
/**
|
||||
* Get the encryption flag.
|
||||
*
|
||||
* @return encryption flag
|
||||
*/
|
||||
bool (*get_encryption_flag) (ike_header_t *this);
|
||||
|
||||
/**
|
||||
* Set the encryption flag.
|
||||
*
|
||||
* @param encryption encryption flag
|
||||
*/
|
||||
void (*set_encryption_flag) (ike_header_t *this, bool encryption);
|
||||
|
||||
/**
|
||||
* Get the commit flag.
|
||||
*
|
||||
* @return commit flag
|
||||
*/
|
||||
bool (*get_commit_flag) (ike_header_t *this);
|
||||
|
||||
/**
|
||||
* Set the commit flag.
|
||||
*
|
||||
* @param commit commit flag
|
||||
*/
|
||||
void (*set_commit_flag) (ike_header_t *this, bool commit);
|
||||
|
||||
/**
|
||||
* Get the authentication only flag.
|
||||
*
|
||||
* @return authonly flag
|
||||
*/
|
||||
bool (*get_authonly_flag) (ike_header_t *this);
|
||||
|
||||
/**
|
||||
* Set the authentication only flag.
|
||||
*
|
||||
* @param authonly authonly flag
|
||||
*/
|
||||
void (*set_authonly_flag) (ike_header_t *this, bool authonly);
|
||||
|
||||
/**
|
||||
* Get the exchange type.
|
||||
*
|
||||
* @return exchange type
|
||||
* @return exchange type
|
||||
*/
|
||||
u_int8_t (*get_exchange_type) (ike_header_t *this);
|
||||
|
||||
|
@ -227,7 +305,7 @@ struct ike_header_t {
|
|||
/**
|
||||
* Get the message id.
|
||||
*
|
||||
* @return message id
|
||||
* @return message id
|
||||
*/
|
||||
u_int32_t (*get_message_id) (ike_header_t *this);
|
||||
|
||||
|
@ -245,10 +323,17 @@ struct ike_header_t {
|
|||
};
|
||||
|
||||
/**
|
||||
* Create an ike_header_t object
|
||||
* Create an empty ike_header_t object.
|
||||
*
|
||||
* @return ike_header_t object
|
||||
*/
|
||||
ike_header_t *ike_header_create(void);
|
||||
|
||||
/**
|
||||
* Create an ike_header_t object for a specific major/minor version
|
||||
*
|
||||
* @return ike_header_t object
|
||||
*/
|
||||
ike_header_t *ike_header_create_version(int major, int minor);
|
||||
|
||||
#endif /** IKE_HEADER_H_ @}*/
|
||||
|
|
|
@ -67,15 +67,17 @@ struct private_ke_payload_t {
|
|||
* Key Exchange Data of this KE payload.
|
||||
*/
|
||||
chunk_t key_exchange_data;
|
||||
|
||||
/**
|
||||
* Payload type, KEY_EXCHANGE or KEY_EXCHANGE_V1
|
||||
*/
|
||||
payload_type_t type;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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 rules for IKEv2 key exchange payload.
|
||||
*/
|
||||
encoding_rule_t ke_payload_encodings[] = {
|
||||
static encoding_rule_t encodings_v2[] = {
|
||||
/* 1 Byte next payload type, stored in the field next_payload */
|
||||
{ U_INT_8, offsetof(private_ke_payload_t, next_payload) },
|
||||
/* the critical bit */
|
||||
|
@ -96,7 +98,7 @@ encoding_rule_t ke_payload_encodings[] = {
|
|||
{ RESERVED_BYTE, offsetof(private_ke_payload_t, reserved_byte[0])},
|
||||
{ RESERVED_BYTE, offsetof(private_ke_payload_t, reserved_byte[1])},
|
||||
/* Key Exchange Data is from variable size */
|
||||
{ KEY_EXCHANGE_DATA, offsetof(private_ke_payload_t, key_exchange_data)}
|
||||
{ CHUNK_DATA, offsetof(private_ke_payload_t, key_exchange_data)},
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -113,23 +115,62 @@ encoding_rule_t ke_payload_encodings[] = {
|
|||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
static encoding_rule_t encodings_v1[] = {
|
||||
/* 1 Byte next payload type, stored in the field next_payload */
|
||||
{ U_INT_8, offsetof(private_ke_payload_t, next_payload) },
|
||||
/* Reserved Byte */
|
||||
{ RESERVED_BYTE, offsetof(private_ke_payload_t, reserved_byte[0])},
|
||||
/* Length of the whole payload*/
|
||||
{ PAYLOAD_LENGTH, offsetof(private_ke_payload_t, payload_length) },
|
||||
/* Key Exchange Data is from variable size */
|
||||
{ CHUNK_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 ! RESERVED ! Payload Length !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! !
|
||||
~ Key Exchange Data ~
|
||||
! !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
|
||||
METHOD(payload_t, verify, status_t,
|
||||
private_ke_payload_t *this)
|
||||
{
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_encoding_rules, void,
|
||||
private_ke_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
|
||||
METHOD(payload_t, get_encoding_rules, int,
|
||||
private_ke_payload_t *this, encoding_rule_t **rules)
|
||||
{
|
||||
*rules = ke_payload_encodings;
|
||||
*rule_count = countof(ke_payload_encodings);
|
||||
if (this->type == KEY_EXCHANGE)
|
||||
{
|
||||
*rules = encodings_v2;
|
||||
return countof(encodings_v2);
|
||||
}
|
||||
*rules = encodings_v1;
|
||||
return countof(encodings_v1);
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_header_length, int,
|
||||
private_ke_payload_t *this)
|
||||
{
|
||||
if (this->type == KEY_EXCHANGE)
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
return 4;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_type, payload_type_t,
|
||||
private_ke_payload_t *this)
|
||||
{
|
||||
return KEY_EXCHANGE;
|
||||
return this->type;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_next_type, payload_type_t,
|
||||
|
@ -172,7 +213,7 @@ METHOD2(payload_t, ke_payload_t, destroy, void,
|
|||
/*
|
||||
* Described in header
|
||||
*/
|
||||
ke_payload_t *ke_payload_create()
|
||||
ke_payload_t *ke_payload_create(payload_type_t type)
|
||||
{
|
||||
private_ke_payload_t *this;
|
||||
|
||||
|
@ -181,6 +222,7 @@ ke_payload_t *ke_payload_create()
|
|||
.payload_interface = {
|
||||
.verify = _verify,
|
||||
.get_encoding_rules = _get_encoding_rules,
|
||||
.get_header_length = _get_header_length,
|
||||
.get_length = _get_length,
|
||||
.get_next_type = _get_next_type,
|
||||
.set_next_type = _set_next_type,
|
||||
|
@ -192,22 +234,24 @@ ke_payload_t *ke_payload_create()
|
|||
.destroy = _destroy,
|
||||
},
|
||||
.next_payload = NO_PAYLOAD,
|
||||
.payload_length = KE_PAYLOAD_HEADER_LENGTH,
|
||||
.dh_group_number = MODP_NONE,
|
||||
.type = type,
|
||||
);
|
||||
this->payload_length = get_header_length(this);
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header
|
||||
*/
|
||||
ke_payload_t *ke_payload_create_from_diffie_hellman(diffie_hellman_t *dh)
|
||||
ke_payload_t *ke_payload_create_from_diffie_hellman(payload_type_t type,
|
||||
diffie_hellman_t *dh)
|
||||
{
|
||||
private_ke_payload_t *this = (private_ke_payload_t*)ke_payload_create();
|
||||
private_ke_payload_t *this = (private_ke_payload_t*)ke_payload_create(type);
|
||||
|
||||
dh->get_my_public_value(dh, &this->key_exchange_data);
|
||||
this->dh_group_number = dh->get_dh_group(dh);
|
||||
this->payload_length = this->key_exchange_data.len + KE_PAYLOAD_HEADER_LENGTH;
|
||||
this->payload_length += this->key_exchange_data.len;
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
|
|
@ -31,16 +31,10 @@ typedef struct ke_payload_t ke_payload_t;
|
|||
#include <crypto/diffie_hellman.h>
|
||||
|
||||
/**
|
||||
* KE payload length in bytes without any key exchange data.
|
||||
*/
|
||||
#define KE_PAYLOAD_HEADER_LENGTH 8
|
||||
|
||||
/**
|
||||
* Class representing an IKEv2-KE Payload.
|
||||
*
|
||||
* The KE Payload format is described in RFC section 3.4.
|
||||
* Class representing an IKEv1 or IKEv2 key exchange payload.
|
||||
*/
|
||||
struct ke_payload_t {
|
||||
|
||||
/**
|
||||
* The payload_t interface.
|
||||
*/
|
||||
|
@ -54,32 +48,34 @@ struct ke_payload_t {
|
|||
chunk_t (*get_key_exchange_data) (ke_payload_t *this);
|
||||
|
||||
/**
|
||||
* Gets the Diffie-Hellman Group Number of this KE payload.
|
||||
* Gets the Diffie-Hellman Group Number of this KE payload (IKEv2 only).
|
||||
*
|
||||
* @return DH Group Number of this payload
|
||||
*/
|
||||
diffie_hellman_group_t (*get_dh_group_number) (ke_payload_t *this);
|
||||
|
||||
/**
|
||||
* Destroys an ke_payload_t object.
|
||||
* Destroys a ke_payload_t object.
|
||||
*/
|
||||
void (*destroy) (ke_payload_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates an empty ke_payload_t object
|
||||
* Creates an empty ke_payload_t object.
|
||||
*
|
||||
* @return ke_payload_t object
|
||||
* @param type KEY_EXCHANGE or KEY_EXCHANGE_V1
|
||||
* @return ke_payload_t object
|
||||
*/
|
||||
ke_payload_t *ke_payload_create(void);
|
||||
ke_payload_t *ke_payload_create(payload_type_t type);
|
||||
|
||||
/**
|
||||
* Creates a ke_payload_t from a diffie_hellman_t
|
||||
* Creates a ke_payload_t from a diffie_hellman_t.
|
||||
*
|
||||
* @param diffie_hellman diffie hellman object containing group and key
|
||||
* @return ke_payload_t object
|
||||
* @param type KEY_EXCHANGE or KEY_EXCHANGE_V1
|
||||
* @param dh diffie hellman object containing group and key
|
||||
* @return ke_payload_t object
|
||||
*/
|
||||
ke_payload_t *ke_payload_create_from_diffie_hellman(
|
||||
diffie_hellman_t *diffie_hellman);
|
||||
ke_payload_t *ke_payload_create_from_diffie_hellman(payload_type_t type,
|
||||
diffie_hellman_t *dh);
|
||||
|
||||
#endif /** KE_PAYLOAD_H_ @}*/
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "nonce_payload.h"
|
||||
|
||||
#include <daemon.h>
|
||||
#include <encoding/payloads/encodings.h>
|
||||
|
||||
typedef struct private_nonce_payload_t private_nonce_payload_t;
|
||||
|
@ -57,6 +58,11 @@ struct private_nonce_payload_t {
|
|||
* The contained nonce value.
|
||||
*/
|
||||
chunk_t nonce;
|
||||
|
||||
/**
|
||||
* Payload type, NONCE or NONCE_V1
|
||||
*/
|
||||
payload_type_t type;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -65,7 +71,7 @@ struct private_nonce_payload_t {
|
|||
* The defined offsets are the positions in a object of type
|
||||
* private_nonce_payload_t.
|
||||
*/
|
||||
encoding_rule_t nonce_payload_encodings[] = {
|
||||
static encoding_rule_t 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 */
|
||||
|
@ -81,7 +87,7 @@ encoding_rule_t nonce_payload_encodings[] = {
|
|||
/* 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) },
|
||||
{ CHUNK_DATA, offsetof(private_nonce_payload_t, nonce) },
|
||||
};
|
||||
|
||||
/* 1 2 3
|
||||
|
@ -98,24 +104,48 @@ encoding_rule_t nonce_payload_encodings[] = {
|
|||
METHOD(payload_t, verify, status_t,
|
||||
private_nonce_payload_t *this)
|
||||
{
|
||||
if (this->nonce.len < 16 || this->nonce.len > 256)
|
||||
bool bad_length = FALSE;
|
||||
|
||||
if (this->nonce.len > 256)
|
||||
{
|
||||
bad_length = TRUE;
|
||||
}
|
||||
if (this->type == NONCE &&
|
||||
this->nonce.len < 16)
|
||||
{
|
||||
bad_length = TRUE;
|
||||
}
|
||||
if (this->type == NONCE_V1 &&
|
||||
this->nonce.len < 8)
|
||||
{
|
||||
bad_length = TRUE;
|
||||
}
|
||||
if (bad_length)
|
||||
{
|
||||
DBG1(DBG_ENC, "%N payload has invalid length (%d bytes)",
|
||||
payload_type_names, this->type, this->nonce.len);
|
||||
return FAILED;
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_encoding_rules, void,
|
||||
private_nonce_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
|
||||
METHOD(payload_t, get_encoding_rules, int,
|
||||
private_nonce_payload_t *this, encoding_rule_t **rules)
|
||||
{
|
||||
*rules = nonce_payload_encodings;
|
||||
*rule_count = countof(nonce_payload_encodings);
|
||||
*rules = encodings;
|
||||
return countof(encodings);
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_header_length, int,
|
||||
private_nonce_payload_t *this)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_type, payload_type_t,
|
||||
private_nonce_payload_t *this)
|
||||
{
|
||||
return NONCE;
|
||||
return this->type;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_next_type, payload_type_t,
|
||||
|
@ -140,7 +170,7 @@ METHOD(nonce_payload_t, set_nonce, void,
|
|||
private_nonce_payload_t *this, chunk_t nonce)
|
||||
{
|
||||
this->nonce = chunk_clone(nonce);
|
||||
this->payload_length = NONCE_PAYLOAD_HEADER_LENGTH + nonce.len;
|
||||
this->payload_length = get_header_length(this) + nonce.len;
|
||||
}
|
||||
|
||||
METHOD(nonce_payload_t, get_nonce, chunk_t,
|
||||
|
@ -159,7 +189,7 @@ METHOD2(payload_t, nonce_payload_t, destroy, void,
|
|||
/*
|
||||
* Described in header
|
||||
*/
|
||||
nonce_payload_t *nonce_payload_create()
|
||||
nonce_payload_t *nonce_payload_create(payload_type_t type)
|
||||
{
|
||||
private_nonce_payload_t *this;
|
||||
|
||||
|
@ -168,6 +198,7 @@ nonce_payload_t *nonce_payload_create()
|
|||
.payload_interface = {
|
||||
.verify = _verify,
|
||||
.get_encoding_rules = _get_encoding_rules,
|
||||
.get_header_length = _get_header_length,
|
||||
.get_length = _get_length,
|
||||
.get_next_type = _get_next_type,
|
||||
.set_next_type = _set_next_type,
|
||||
|
@ -179,7 +210,8 @@ nonce_payload_t *nonce_payload_create()
|
|||
.destroy = _destroy,
|
||||
},
|
||||
.next_payload = NO_PAYLOAD,
|
||||
.payload_length = NONCE_PAYLOAD_HEADER_LENGTH,
|
||||
.payload_length = get_header_length(this),
|
||||
.type = type,
|
||||
);
|
||||
return &this->public;
|
||||
}
|
||||
|
|
|
@ -33,14 +33,7 @@ typedef struct nonce_payload_t nonce_payload_t;
|
|||
#define NONCE_SIZE 32
|
||||
|
||||
/**
|
||||
* Length of a nonce payload without a nonce in bytes.
|
||||
*/
|
||||
#define NONCE_PAYLOAD_HEADER_LENGTH 4
|
||||
|
||||
/**
|
||||
* Object representing an IKEv2 Nonce payload.
|
||||
*
|
||||
* The Nonce payload format is described in RFC section 3.3.
|
||||
* Object representing an IKEv1/IKEv2 Nonce payload.
|
||||
*/
|
||||
struct nonce_payload_t {
|
||||
/**
|
||||
|
@ -71,8 +64,9 @@ struct nonce_payload_t {
|
|||
/**
|
||||
* Creates an empty nonce_payload_t object
|
||||
*
|
||||
* @return nonce_payload_t object
|
||||
* @param type NONCE or NONCE_V1
|
||||
* @return nonce_payload_t object
|
||||
*/
|
||||
nonce_payload_t *nonce_payload_create(void);
|
||||
nonce_payload_t *nonce_payload_create(payload_type_t type);
|
||||
|
||||
#endif /** NONCE_PAYLOAD_H_ @}*/
|
||||
|
|
|
@ -36,11 +36,18 @@ ENUM_NEXT(notify_type_names, INVALID_MESSAGE_ID, INVALID_MESSAGE_ID, INVALID_SYN
|
|||
"INVALID_MESSAGE_ID");
|
||||
ENUM_NEXT(notify_type_names, INVALID_SPI, INVALID_SPI, INVALID_MESSAGE_ID,
|
||||
"INVALID_SPI");
|
||||
ENUM_NEXT(notify_type_names, NO_PROPOSAL_CHOSEN, NO_PROPOSAL_CHOSEN, INVALID_SPI,
|
||||
ENUM_NEXT(notify_type_names, ATTRIBUTES_NOT_SUPPORTED, NO_PROPOSAL_CHOSEN, INVALID_SPI,
|
||||
"ATTRIBUTES_NOT_SUPPORTED",
|
||||
"NO_PROPOSAL_CHOSEN");
|
||||
ENUM_NEXT(notify_type_names, INVALID_KE_PAYLOAD, INVALID_KE_PAYLOAD, NO_PROPOSAL_CHOSEN,
|
||||
"INVALID_KE_PAYLOAD");
|
||||
ENUM_NEXT(notify_type_names, AUTHENTICATION_FAILED, AUTHENTICATION_FAILED, INVALID_KE_PAYLOAD,
|
||||
ENUM_NEXT(notify_type_names, PAYLOAD_MALFORMED, AUTHENTICATION_FAILED, NO_PROPOSAL_CHOSEN,
|
||||
"PAYLOAD_MALFORMED",
|
||||
"INVALID_KE_PAYLOAD",
|
||||
"INVALID_ID_INFORMATION",
|
||||
"INVALID_CERT_ENCODING",
|
||||
"INVALID_CERTIFICATE",
|
||||
"CERT_TYPE_UNSUPPORTED",
|
||||
"INVALID_CERT_AUTHORITY",
|
||||
"INVALID_HASH_INFORMATION",
|
||||
"AUTHENTICATION_FAILED");
|
||||
ENUM_NEXT(notify_type_names, SINGLE_PAIR_REQUIRED, CHILD_SA_NOT_FOUND, AUTHENTICATION_FAILED,
|
||||
"SINGLE_PAIR_REQUIRED",
|
||||
|
@ -99,7 +106,14 @@ ENUM_NEXT(notify_type_names, INITIAL_CONTACT, IPSEC_REPLAY_COUNTER_SYNC, MS_NOTI
|
|||
"IKEV2_REPLAY_COUNTER_SYNC_SUPPORTED",
|
||||
"IKEV2_MESSAGE_ID_SYNC",
|
||||
"IPSEC_REPLAY_COUNTER_SYNC");
|
||||
ENUM_NEXT(notify_type_names, USE_BEET_MODE, USE_BEET_MODE, IPSEC_REPLAY_COUNTER_SYNC,
|
||||
ENUM_NEXT(notify_type_names, INITIAL_CONTACT_IKEV1, INITIAL_CONTACT_IKEV1, IPSEC_REPLAY_COUNTER_SYNC,
|
||||
"INITIAL_CONTACT");
|
||||
ENUM_NEXT(notify_type_names, DPD_R_U_THERE, DPD_R_U_THERE_ACK, INITIAL_CONTACT_IKEV1,
|
||||
"DPD_R_U_THERE",
|
||||
"DPD_R_U_THERE_ACK");
|
||||
ENUM_NEXT(notify_type_names, UNITY_LOAD_BALANCE, UNITY_LOAD_BALANCE, DPD_R_U_THERE_ACK,
|
||||
"UNITY_LOAD_BALANCE");
|
||||
ENUM_NEXT(notify_type_names, USE_BEET_MODE, USE_BEET_MODE, UNITY_LOAD_BALANCE,
|
||||
"USE_BEET_MODE");
|
||||
ENUM_NEXT(notify_type_names, ME_MEDIATION, RADIUS_ATTRIBUTE, USE_BEET_MODE,
|
||||
"ME_MEDIATION",
|
||||
|
@ -124,11 +138,18 @@ ENUM_NEXT(notify_type_short_names, INVALID_MESSAGE_ID, INVALID_MESSAGE_ID, INVAL
|
|||
"INVAL_MID");
|
||||
ENUM_NEXT(notify_type_short_names, INVALID_SPI, INVALID_SPI, INVALID_MESSAGE_ID,
|
||||
"INVAL_SPI");
|
||||
ENUM_NEXT(notify_type_short_names, NO_PROPOSAL_CHOSEN, NO_PROPOSAL_CHOSEN, INVALID_SPI,
|
||||
ENUM_NEXT(notify_type_short_names, ATTRIBUTES_NOT_SUPPORTED, NO_PROPOSAL_CHOSEN, INVALID_SPI,
|
||||
"ATTR_UNSUP",
|
||||
"NO_PROP");
|
||||
ENUM_NEXT(notify_type_short_names, INVALID_KE_PAYLOAD, INVALID_KE_PAYLOAD, NO_PROPOSAL_CHOSEN,
|
||||
"INVAL_KE");
|
||||
ENUM_NEXT(notify_type_short_names, AUTHENTICATION_FAILED, AUTHENTICATION_FAILED, INVALID_KE_PAYLOAD,
|
||||
ENUM_NEXT(notify_type_short_names, PAYLOAD_MALFORMED, AUTHENTICATION_FAILED, NO_PROPOSAL_CHOSEN,
|
||||
"PLD_MAL",
|
||||
"INVAL_KE",
|
||||
"INVAL_ID",
|
||||
"INVAL_CERTEN",
|
||||
"INVAL_CERT",
|
||||
"CERT_UNSUP",
|
||||
"INVAL_CA",
|
||||
"INVAL_HASH",
|
||||
"AUTH_FAILED");
|
||||
ENUM_NEXT(notify_type_short_names, SINGLE_PAIR_REQUIRED, CHILD_SA_NOT_FOUND, AUTHENTICATION_FAILED,
|
||||
"SINGLE_PAIR",
|
||||
|
@ -187,7 +208,14 @@ ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT, IPSEC_REPLAY_COUNTER_SYNC, M
|
|||
"RPL_CTR_SYN_SUP",
|
||||
"MSG_ID_SYN",
|
||||
"RPL_CTR_SYN");
|
||||
ENUM_NEXT(notify_type_short_names, USE_BEET_MODE, USE_BEET_MODE, IPSEC_REPLAY_COUNTER_SYNC,
|
||||
ENUM_NEXT(notify_type_short_names, INITIAL_CONTACT_IKEV1, INITIAL_CONTACT_IKEV1, IPSEC_REPLAY_COUNTER_SYNC,
|
||||
"INITIAL_CONTACT");
|
||||
ENUM_NEXT(notify_type_short_names, DPD_R_U_THERE, DPD_R_U_THERE_ACK, INITIAL_CONTACT_IKEV1,
|
||||
"DPD",
|
||||
"DPD_ACK");
|
||||
ENUM_NEXT(notify_type_short_names, UNITY_LOAD_BALANCE, UNITY_LOAD_BALANCE, DPD_R_U_THERE_ACK,
|
||||
"UNITY_LB");
|
||||
ENUM_NEXT(notify_type_short_names, USE_BEET_MODE, USE_BEET_MODE, UNITY_LOAD_BALANCE,
|
||||
"BEET_MODE");
|
||||
ENUM_NEXT(notify_type_short_names, ME_MEDIATION, RADIUS_ATTRIBUTE, USE_BEET_MODE,
|
||||
"ME_MED",
|
||||
|
@ -226,13 +254,18 @@ struct private_notify_payload_t {
|
|||
/**
|
||||
* reserved bits
|
||||
*/
|
||||
bool reserved[7];
|
||||
bool reserved[8];
|
||||
|
||||
/**
|
||||
* Length of this payload.
|
||||
*/
|
||||
u_int16_t payload_length;
|
||||
|
||||
/**
|
||||
* Domain of interpretation, IKEv1 only.
|
||||
*/
|
||||
u_int32_t doi;
|
||||
|
||||
/**
|
||||
* Protocol id.
|
||||
*/
|
||||
|
@ -256,40 +289,42 @@ struct private_notify_payload_t {
|
|||
/**
|
||||
* Notification data.
|
||||
*/
|
||||
chunk_t notification_data;
|
||||
chunk_t notify_data;
|
||||
|
||||
/**
|
||||
* Type of payload, NOTIFY or NOTIFY_V1
|
||||
*/
|
||||
payload_type_t type;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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 rules for an IKEv2 notification payload
|
||||
*/
|
||||
encoding_rule_t notify_payload_encodings[] = {
|
||||
static encoding_rule_t encodings_v2[] = {
|
||||
/* 1 Byte next payload type, stored in the field next_payload */
|
||||
{ U_INT_8, offsetof(private_notify_payload_t, next_payload) },
|
||||
{ U_INT_8, offsetof(private_notify_payload_t, next_payload) },
|
||||
/* the critical bit */
|
||||
{ FLAG, offsetof(private_notify_payload_t, critical) },
|
||||
{ FLAG, offsetof(private_notify_payload_t, critical) },
|
||||
/* 7 Bit reserved bits, nowhere stored */
|
||||
{ RESERVED_BIT, offsetof(private_notify_payload_t, reserved[0]) },
|
||||
{ RESERVED_BIT, offsetof(private_notify_payload_t, reserved[1]) },
|
||||
{ RESERVED_BIT, offsetof(private_notify_payload_t, reserved[2]) },
|
||||
{ RESERVED_BIT, offsetof(private_notify_payload_t, reserved[3]) },
|
||||
{ RESERVED_BIT, offsetof(private_notify_payload_t, reserved[4]) },
|
||||
{ RESERVED_BIT, offsetof(private_notify_payload_t, reserved[5]) },
|
||||
{ RESERVED_BIT, offsetof(private_notify_payload_t, reserved[6]) },
|
||||
{ RESERVED_BIT, offsetof(private_notify_payload_t, reserved[0]) },
|
||||
{ RESERVED_BIT, offsetof(private_notify_payload_t, reserved[1]) },
|
||||
{ RESERVED_BIT, offsetof(private_notify_payload_t, reserved[2]) },
|
||||
{ RESERVED_BIT, offsetof(private_notify_payload_t, reserved[3]) },
|
||||
{ RESERVED_BIT, offsetof(private_notify_payload_t, reserved[4]) },
|
||||
{ RESERVED_BIT, offsetof(private_notify_payload_t, reserved[5]) },
|
||||
{ RESERVED_BIT, offsetof(private_notify_payload_t, reserved[6]) },
|
||||
/* Length of the whole payload*/
|
||||
{ PAYLOAD_LENGTH, offsetof(private_notify_payload_t, payload_length) },
|
||||
{ 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) },
|
||||
{ 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) },
|
||||
{ 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_type) },
|
||||
{ U_INT_16, offsetof(private_notify_payload_t, notify_type) },
|
||||
/* SPI as variable length field*/
|
||||
{ SPI, offsetof(private_notify_payload_t, spi) },
|
||||
{ SPI, offsetof(private_notify_payload_t, spi) },
|
||||
/* Key Exchange Data is from variable size */
|
||||
{ NOTIFICATION_DATA,offsetof(private_notify_payload_t, notification_data) }
|
||||
{ CHUNK_DATA, offsetof(private_notify_payload_t, notify_data) },
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -309,6 +344,57 @@ encoding_rule_t notify_payload_encodings[] = {
|
|||
! !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
/**
|
||||
* Encoding rules for an IKEv1 notification payload
|
||||
*/
|
||||
static encoding_rule_t encodings_v1[] = {
|
||||
/* 1 Byte next payload type, stored in the field next_payload */
|
||||
{ U_INT_8, offsetof(private_notify_payload_t, next_payload) },
|
||||
/* 8 reserved bits */
|
||||
{ RESERVED_BIT, offsetof(private_notify_payload_t, reserved[0]) },
|
||||
{ RESERVED_BIT, offsetof(private_notify_payload_t, reserved[1]) },
|
||||
{ RESERVED_BIT, offsetof(private_notify_payload_t, reserved[2]) },
|
||||
{ RESERVED_BIT, offsetof(private_notify_payload_t, reserved[3]) },
|
||||
{ RESERVED_BIT, offsetof(private_notify_payload_t, reserved[4]) },
|
||||
{ RESERVED_BIT, offsetof(private_notify_payload_t, reserved[5]) },
|
||||
{ RESERVED_BIT, offsetof(private_notify_payload_t, reserved[6]) },
|
||||
{ RESERVED_BIT, offsetof(private_notify_payload_t, reserved[7]) },
|
||||
/* Length of the whole payload*/
|
||||
{ PAYLOAD_LENGTH, offsetof(private_notify_payload_t, payload_length) },
|
||||
/* DOI as 32 bit field*/
|
||||
{ U_INT_32, offsetof(private_notify_payload_t, doi) },
|
||||
/* 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_type) },
|
||||
/* SPI as variable length field*/
|
||||
{ SPI, offsetof(private_notify_payload_t, spi) },
|
||||
/* Key Exchange Data is from variable size */
|
||||
{ CHUNK_DATA, offsetof(private_notify_payload_t, notify_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 ! RESERVED ! Payload Length !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! DOI !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! Protocol ID ! SPI Size ! Notify Message Type !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! !
|
||||
~ Security Parameter Index (SPI) ~
|
||||
! !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! !
|
||||
~ Notification Data ~
|
||||
! !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
|
||||
METHOD(payload_t, verify, status_t,
|
||||
private_notify_payload_t *this)
|
||||
|
@ -331,7 +417,7 @@ METHOD(payload_t, verify, status_t,
|
|||
{
|
||||
case INVALID_KE_PAYLOAD:
|
||||
{
|
||||
if (this->notification_data.len != 2)
|
||||
if (this->type == NOTIFY && this->notify_data.len != 2)
|
||||
{
|
||||
bad_length = TRUE;
|
||||
}
|
||||
|
@ -341,7 +427,7 @@ METHOD(payload_t, verify, status_t,
|
|||
case NAT_DETECTION_DESTINATION_IP:
|
||||
case ME_CONNECTAUTH:
|
||||
{
|
||||
if (this->notification_data.len != HASH_SIZE_SHA1)
|
||||
if (this->notify_data.len != HASH_SIZE_SHA1)
|
||||
{
|
||||
bad_length = TRUE;
|
||||
}
|
||||
|
@ -351,7 +437,7 @@ METHOD(payload_t, verify, status_t,
|
|||
case INVALID_MAJOR_VERSION:
|
||||
case NO_PROPOSAL_CHOSEN:
|
||||
{
|
||||
if (this->notification_data.len != 0)
|
||||
if (this->type == NOTIFY && this->notify_data.len != 0)
|
||||
{
|
||||
bad_length = TRUE;
|
||||
}
|
||||
|
@ -359,7 +445,7 @@ METHOD(payload_t, verify, status_t,
|
|||
}
|
||||
case ADDITIONAL_IP4_ADDRESS:
|
||||
{
|
||||
if (this->notification_data.len != 4)
|
||||
if (this->notify_data.len != 4)
|
||||
{
|
||||
bad_length = TRUE;
|
||||
}
|
||||
|
@ -367,7 +453,7 @@ METHOD(payload_t, verify, status_t,
|
|||
}
|
||||
case ADDITIONAL_IP6_ADDRESS:
|
||||
{
|
||||
if (this->notification_data.len != 16)
|
||||
if (this->notify_data.len != 16)
|
||||
{
|
||||
bad_length = TRUE;
|
||||
}
|
||||
|
@ -375,7 +461,7 @@ METHOD(payload_t, verify, status_t,
|
|||
}
|
||||
case AUTH_LIFETIME:
|
||||
{
|
||||
if (this->notification_data.len != 4)
|
||||
if (this->notify_data.len != 4)
|
||||
{
|
||||
bad_length = TRUE;
|
||||
}
|
||||
|
@ -383,30 +469,37 @@ METHOD(payload_t, verify, status_t,
|
|||
}
|
||||
case IPCOMP_SUPPORTED:
|
||||
{
|
||||
if (this->notification_data.len != 3)
|
||||
if (this->notify_data.len != 3)
|
||||
{
|
||||
bad_length = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ME_ENDPOINT:
|
||||
if (this->notification_data.len != 8 &&
|
||||
this->notification_data.len != 12 &&
|
||||
this->notification_data.len != 24)
|
||||
if (this->notify_data.len != 8 &&
|
||||
this->notify_data.len != 12 &&
|
||||
this->notify_data.len != 24)
|
||||
{
|
||||
bad_length = TRUE;
|
||||
}
|
||||
break;
|
||||
case ME_CONNECTID:
|
||||
if (this->notification_data.len < 4 ||
|
||||
this->notification_data.len > 16)
|
||||
if (this->notify_data.len < 4 ||
|
||||
this->notify_data.len > 16)
|
||||
{
|
||||
bad_length = TRUE;
|
||||
}
|
||||
break;
|
||||
case ME_CONNECTKEY:
|
||||
if (this->notification_data.len < 16 ||
|
||||
this->notification_data.len > 32)
|
||||
if (this->notify_data.len < 16 ||
|
||||
this->notify_data.len > 32)
|
||||
{
|
||||
bad_length = TRUE;
|
||||
}
|
||||
break;
|
||||
case DPD_R_U_THERE:
|
||||
case DPD_R_U_THERE_ACK:
|
||||
if (this->notify_data.len != 4)
|
||||
{
|
||||
bad_length = TRUE;
|
||||
}
|
||||
|
@ -419,23 +512,38 @@ METHOD(payload_t, verify, status_t,
|
|||
{
|
||||
DBG1(DBG_ENC, "invalid notify data length for %N (%d)",
|
||||
notify_type_names, this->notify_type,
|
||||
this->notification_data.len);
|
||||
this->notify_data.len);
|
||||
return FAILED;
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_encoding_rules, void,
|
||||
private_notify_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
|
||||
METHOD(payload_t, get_encoding_rules, int,
|
||||
private_notify_payload_t *this, encoding_rule_t **rules)
|
||||
{
|
||||
*rules = notify_payload_encodings;
|
||||
*rule_count = countof(notify_payload_encodings);
|
||||
if (this->type == NOTIFY)
|
||||
{
|
||||
*rules = encodings_v2;
|
||||
return countof(encodings_v2);
|
||||
}
|
||||
*rules = encodings_v1;
|
||||
return countof(encodings_v1);
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_header_length, int,
|
||||
private_notify_payload_t *this)
|
||||
{
|
||||
if (this->type == NOTIFY)
|
||||
{
|
||||
return 8 + this->spi_size;
|
||||
}
|
||||
return 12 + this->spi_size;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_type, payload_type_t,
|
||||
private_notify_payload_t *this)
|
||||
{
|
||||
return NOTIFY;
|
||||
return this->type;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_next_type, payload_type_t,
|
||||
|
@ -453,19 +561,9 @@ METHOD(payload_t, set_next_type, void,
|
|||
/**
|
||||
* recompute the payloads length.
|
||||
*/
|
||||
static void compute_length (private_notify_payload_t *this)
|
||||
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;
|
||||
this->payload_length = get_header_length(this) + this->notify_data.len;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_length, size_t,
|
||||
|
@ -533,24 +631,55 @@ METHOD(notify_payload_t, set_spi, void,
|
|||
compute_length(this);
|
||||
}
|
||||
|
||||
METHOD(notify_payload_t, get_spi_data, chunk_t,
|
||||
private_notify_payload_t *this)
|
||||
{
|
||||
switch (this->protocol_id)
|
||||
{
|
||||
case PROTO_IKE:
|
||||
if (this->spi.len == 16)
|
||||
{
|
||||
return this->spi;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return chunk_empty;
|
||||
}
|
||||
|
||||
METHOD(notify_payload_t, set_spi_data, void,
|
||||
private_notify_payload_t *this, chunk_t spi)
|
||||
{
|
||||
chunk_free(&this->spi);
|
||||
switch (this->protocol_id)
|
||||
{
|
||||
case PROTO_IKE:
|
||||
this->spi = chunk_clone(spi);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
this->spi_size = this->spi.len;
|
||||
compute_length(this);
|
||||
}
|
||||
|
||||
METHOD(notify_payload_t, get_notification_data, chunk_t,
|
||||
private_notify_payload_t *this)
|
||||
{
|
||||
return this->notification_data;
|
||||
return this->notify_data;
|
||||
}
|
||||
|
||||
METHOD(notify_payload_t, set_notification_data, void,
|
||||
private_notify_payload_t *this, chunk_t data)
|
||||
{
|
||||
free(this->notification_data.ptr);
|
||||
this->notification_data = chunk_clone(data);
|
||||
free(this->notify_data.ptr);
|
||||
this->notify_data = chunk_clone(data);
|
||||
compute_length(this);
|
||||
}
|
||||
|
||||
METHOD2(payload_t, notify_payload_t, destroy, void,
|
||||
private_notify_payload_t *this)
|
||||
{
|
||||
free(this->notification_data.ptr);
|
||||
free(this->notify_data.ptr);
|
||||
free(this->spi.ptr);
|
||||
free(this);
|
||||
}
|
||||
|
@ -558,7 +687,7 @@ METHOD2(payload_t, notify_payload_t, destroy, void,
|
|||
/*
|
||||
* Described in header
|
||||
*/
|
||||
notify_payload_t *notify_payload_create()
|
||||
notify_payload_t *notify_payload_create(payload_type_t type)
|
||||
{
|
||||
private_notify_payload_t *this;
|
||||
|
||||
|
@ -567,6 +696,7 @@ notify_payload_t *notify_payload_create()
|
|||
.payload_interface = {
|
||||
.verify = _verify,
|
||||
.get_encoding_rules = _get_encoding_rules,
|
||||
.get_header_length = _get_header_length,
|
||||
.get_length = _get_length,
|
||||
.get_next_type = _get_next_type,
|
||||
.set_next_type = _set_next_type,
|
||||
|
@ -579,13 +709,17 @@ notify_payload_t *notify_payload_create()
|
|||
.set_notify_type = _set_notify_type,
|
||||
.get_spi = _get_spi,
|
||||
.set_spi = _set_spi,
|
||||
.get_spi_data = _get_spi_data,
|
||||
.set_spi_data = _set_spi_data,
|
||||
.get_notification_data = _get_notification_data,
|
||||
.set_notification_data = _set_notification_data,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.doi = IKEV1_DOI_IPSEC,
|
||||
.next_payload = NO_PAYLOAD,
|
||||
.payload_length = NOTIFY_PAYLOAD_HEADER_LENGTH,
|
||||
.type = type,
|
||||
);
|
||||
compute_length(this);
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
|
@ -593,12 +727,12 @@ notify_payload_t *notify_payload_create()
|
|||
* Described in header.
|
||||
*/
|
||||
notify_payload_t *notify_payload_create_from_protocol_and_type(
|
||||
protocol_id_t protocol_id, notify_type_t notify_type)
|
||||
payload_type_t type, protocol_id_t protocol, notify_type_t notify)
|
||||
{
|
||||
notify_payload_t *notify = notify_payload_create();
|
||||
notify_payload_t *this = notify_payload_create(type);
|
||||
|
||||
notify->set_notify_type(notify, notify_type);
|
||||
notify->set_protocol_id(notify, protocol_id);
|
||||
this->set_notify_type(this, notify);
|
||||
this->set_protocol_id(this, protocol);
|
||||
|
||||
return notify;
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -33,25 +33,36 @@ typedef struct notify_payload_t notify_payload_t;
|
|||
#include <utils/linked_list.h>
|
||||
|
||||
/**
|
||||
* Notify payload length in bytes without any spi and notification data.
|
||||
*/
|
||||
#define NOTIFY_PAYLOAD_HEADER_LENGTH 8
|
||||
|
||||
/**
|
||||
* Notify message types.
|
||||
*
|
||||
* See IKEv2 RFC 3.10.1.
|
||||
* Notify message types for IKEv2, and a subset for IKEv1.
|
||||
*/
|
||||
enum notify_type_t {
|
||||
/* notify error messages */
|
||||
UNSUPPORTED_CRITICAL_PAYLOAD = 1,
|
||||
/* IKEv1 alias */
|
||||
INVALID_PAYLOAD_TYPE = 1,
|
||||
INVALID_IKE_SPI = 4,
|
||||
INVALID_MAJOR_VERSION = 5,
|
||||
INVALID_SYNTAX = 7,
|
||||
/* IKEv1 alias */
|
||||
INVALID_EXCHANGE_TYPE = 7,
|
||||
INVALID_MESSAGE_ID = 9,
|
||||
INVALID_SPI = 11,
|
||||
/* IKEv1 only */
|
||||
ATTRIBUTES_NOT_SUPPORTED = 13,
|
||||
/* IKEv1 alias */
|
||||
NO_PROPOSAL_CHOSEN = 14,
|
||||
/* IKEv1 only */
|
||||
PAYLOAD_MALFORMED = 16,
|
||||
INVALID_KE_PAYLOAD = 17,
|
||||
/* IKEv1 alias */
|
||||
INVALID_KEY_INFORMATION = 17,
|
||||
/* IKEv1 only */
|
||||
INVALID_ID_INFORMATION = 18,
|
||||
INVALID_CERT_ENCODING = 19,
|
||||
INVALID_CERTIFICATE = 20,
|
||||
CERT_TYPE_UNSUPPORTED = 21,
|
||||
INVALID_CERT_AUTHORITY = 22,
|
||||
INVALID_HASH_INFORMATION = 23,
|
||||
AUTHENTICATION_FAILED = 24,
|
||||
SINGLE_PAIR_REQUIRED = 34,
|
||||
NO_ADDITIONAL_SAS = 35,
|
||||
|
@ -127,6 +138,13 @@ enum notify_type_t {
|
|||
IKEV2_REPLAY_COUNTER_SYNC_SUPPORTED = 16421,
|
||||
IKEV2_MESSAGE_ID_SYNC = 16422,
|
||||
IPSEC_REPLAY_COUNTER_SYNC = 16423,
|
||||
/* IKEv1 initial contact */
|
||||
INITIAL_CONTACT_IKEV1 = 24578,
|
||||
/* IKEv1 DPD */
|
||||
DPD_R_U_THERE = 36136,
|
||||
DPD_R_U_THERE_ACK = 36137,
|
||||
/* IKEv1 Cisco High Availability */
|
||||
UNITY_LOAD_BALANCE = 40501,
|
||||
/* BEET mode, not even a draft yet. private use */
|
||||
USE_BEET_MODE = 40961,
|
||||
/* IKE-ME, private use */
|
||||
|
@ -208,6 +226,24 @@ struct notify_payload_t {
|
|||
*/
|
||||
void (*set_spi) (notify_payload_t *this, u_int32_t spi);
|
||||
|
||||
/**
|
||||
* Returns the currently set spi of this payload.
|
||||
*
|
||||
* This is only valid for notifys with protocol ISAKMP
|
||||
*
|
||||
* @return SPI value
|
||||
*/
|
||||
chunk_t (*get_spi_data) (notify_payload_t *this);
|
||||
|
||||
/**
|
||||
* Sets the spi of this payload.
|
||||
*
|
||||
* This is only valid for notifys with protocol ISAKMP
|
||||
*
|
||||
* @param spi SPI value
|
||||
*/
|
||||
void (*set_spi_data) (notify_payload_t *this, chunk_t spi);
|
||||
|
||||
/**
|
||||
* Returns the currently set notification data of payload.
|
||||
*
|
||||
|
@ -236,18 +272,20 @@ struct notify_payload_t {
|
|||
/**
|
||||
* Creates an empty notify_payload_t object
|
||||
*
|
||||
* @param type payload type, NOTIFY or NOTIFY_V1
|
||||
* @return created notify_payload_t object
|
||||
*/
|
||||
notify_payload_t *notify_payload_create(void);
|
||||
notify_payload_t *notify_payload_create(payload_type_t type);
|
||||
|
||||
/**
|
||||
* Creates an notify_payload_t object of specific type for specific protocol id.
|
||||
*
|
||||
* @param protocol_id protocol id (IKE, AH or ESP)
|
||||
* @param type notify type (see notify_type_t)
|
||||
* @param type payload type, NOTIFY or NOTIFY_V1
|
||||
* @param protocol protocol id (IKE, AH or ESP)
|
||||
* @param notify type of notify
|
||||
* @return notify_payload_t object
|
||||
*/
|
||||
notify_payload_t *notify_payload_create_from_protocol_and_type(
|
||||
protocol_id_t protocol_id, notify_type_t type);
|
||||
payload_type_t type, protocol_id_t protocol, notify_type_t notify);
|
||||
|
||||
#endif /** NOTIFY_PAYLOAD_H_ @}*/
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#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>
|
||||
|
@ -34,12 +35,30 @@
|
|||
#include <encoding/payloads/cp_payload.h>
|
||||
#include <encoding/payloads/configuration_attribute.h>
|
||||
#include <encoding/payloads/eap_payload.h>
|
||||
#include <encoding/payloads/hash_payload.h>
|
||||
#include <encoding/payloads/unknown_payload.h>
|
||||
|
||||
|
||||
ENUM_BEGIN(payload_type_names, NO_PAYLOAD, NO_PAYLOAD,
|
||||
"NO_PAYLOAD");
|
||||
ENUM_NEXT(payload_type_names, SECURITY_ASSOCIATION, EXTENSIBLE_AUTHENTICATION, NO_PAYLOAD,
|
||||
ENUM_NEXT(payload_type_names, SECURITY_ASSOCIATION_V1, CONFIGURATION_V1, NO_PAYLOAD,
|
||||
"SECURITY_ASSOCIATION_V1",
|
||||
"PROPOSAL_V1",
|
||||
"TRANSFORM_V1",
|
||||
"KEY_EXCHANGE_V1",
|
||||
"ID_V1",
|
||||
"CERTIFICATE_V1",
|
||||
"CERTIFICATE_REQUEST_V1",
|
||||
"HASH_V1",
|
||||
"SIGNATURE_V1",
|
||||
"NONCE_V1",
|
||||
"NOTIFY_V1",
|
||||
"DELETE_V1",
|
||||
"VENDOR_ID_V1",
|
||||
"CONFIGURATION_V1");
|
||||
ENUM_NEXT(payload_type_names, NAT_D_V1, NAT_OA_V1, CONFIGURATION_V1,
|
||||
"NAT_D_V1",
|
||||
"NAT_OA_V1");
|
||||
ENUM_NEXT(payload_type_names, SECURITY_ASSOCIATION, EXTENSIBLE_AUTHENTICATION, NAT_OA_V1,
|
||||
"SECURITY_ASSOCIATION",
|
||||
"KEY_EXCHANGE",
|
||||
"ID_INITIATOR",
|
||||
|
@ -59,28 +78,56 @@ ENUM_NEXT(payload_type_names, SECURITY_ASSOCIATION, EXTENSIBLE_AUTHENTICATION, N
|
|||
#ifdef ME
|
||||
ENUM_NEXT(payload_type_names, ID_PEER, ID_PEER, EXTENSIBLE_AUTHENTICATION,
|
||||
"ID_PEER");
|
||||
ENUM_NEXT(payload_type_names, HEADER, CONFIGURATION_ATTRIBUTE, ID_PEER,
|
||||
ENUM_NEXT(payload_type_names, HEADER, ENCRYPTED_V1, ID_PEER,
|
||||
"HEADER",
|
||||
"PROPOSAL_SUBSTRUCTURE",
|
||||
"PROPOSAL_SUBSTRUCTURE_V1",
|
||||
"TRANSFORM_SUBSTRUCTURE",
|
||||
"TRANSFORM_SUBSTRUCTURE_V1",
|
||||
"TRANSFORM_ATTRIBUTE",
|
||||
"TRANSFORM_ATTRIBUTE_V1",
|
||||
"TRAFFIC_SELECTOR_SUBSTRUCTURE",
|
||||
"CONFIGURATION_ATTRIBUTE");
|
||||
"CONFIGURATION_ATTRIBUTE",
|
||||
"CONFIGURATION_ATTRIBUTE_V1",
|
||||
"ENCRYPTED_V1");
|
||||
#else
|
||||
ENUM_NEXT(payload_type_names, HEADER, CONFIGURATION_ATTRIBUTE, EXTENSIBLE_AUTHENTICATION,
|
||||
ENUM_NEXT(payload_type_names, HEADER, ENCRYPTED_V1, EXTENSIBLE_AUTHENTICATION,
|
||||
"HEADER",
|
||||
"PROPOSAL_SUBSTRUCTURE",
|
||||
"PROPOSAL_SUBSTRUCTURE_V1",
|
||||
"TRANSFORM_SUBSTRUCTURE",
|
||||
"TRANSFORM_SUBSTRUCTURE_V1",
|
||||
"TRANSFORM_ATTRIBUTE",
|
||||
"TRANSFORM_ATTRIBUTE_V1",
|
||||
"TRAFFIC_SELECTOR_SUBSTRUCTURE",
|
||||
"CONFIGURATION_ATTRIBUTE");
|
||||
"CONFIGURATION_ATTRIBUTE",
|
||||
"CONFIGURATION_ATTRIBUTE_V1",
|
||||
"ENCRYPTED_V1");
|
||||
#endif /* ME */
|
||||
ENUM_END(payload_type_names, CONFIGURATION_ATTRIBUTE);
|
||||
ENUM_END(payload_type_names, ENCRYPTED_V1);
|
||||
|
||||
/* short forms of payload names */
|
||||
ENUM_BEGIN(payload_type_short_names, NO_PAYLOAD, NO_PAYLOAD,
|
||||
"--");
|
||||
ENUM_NEXT(payload_type_short_names, SECURITY_ASSOCIATION, EXTENSIBLE_AUTHENTICATION, NO_PAYLOAD,
|
||||
ENUM_NEXT(payload_type_short_names, SECURITY_ASSOCIATION_V1, CONFIGURATION_V1, NO_PAYLOAD,
|
||||
"SA",
|
||||
"PROP",
|
||||
"TRANS",
|
||||
"KE",
|
||||
"ID",
|
||||
"CERT",
|
||||
"CERTREQ",
|
||||
"HASH",
|
||||
"SIG",
|
||||
"No",
|
||||
"N",
|
||||
"D",
|
||||
"V",
|
||||
"CP");
|
||||
ENUM_NEXT(payload_type_short_names, NAT_D_V1, NAT_OA_V1, CONFIGURATION_V1,
|
||||
"NAT-D",
|
||||
"NAT-OA");
|
||||
ENUM_NEXT(payload_type_short_names, SECURITY_ASSOCIATION, EXTENSIBLE_AUTHENTICATION, NAT_OA_V1,
|
||||
"SA",
|
||||
"KE",
|
||||
"IDi",
|
||||
|
@ -100,23 +147,33 @@ ENUM_NEXT(payload_type_short_names, SECURITY_ASSOCIATION, EXTENSIBLE_AUTHENTICAT
|
|||
#ifdef ME
|
||||
ENUM_NEXT(payload_type_short_names, ID_PEER, ID_PEER, EXTENSIBLE_AUTHENTICATION,
|
||||
"IDp");
|
||||
ENUM_NEXT(payload_type_short_names, HEADER, CONFIGURATION_ATTRIBUTE, ID_PEER,
|
||||
ENUM_NEXT(payload_type_short_names, HEADER, ENCRYPTED_V1, ID_PEER,
|
||||
"HDR",
|
||||
"PROP",
|
||||
"PROP",
|
||||
"TRANS",
|
||||
"TRANS",
|
||||
"TRANSATTR",
|
||||
"TRANSATTR",
|
||||
"TSSUB",
|
||||
"CPATTR");
|
||||
"CATTR",
|
||||
"CATTR",
|
||||
"E");
|
||||
#else
|
||||
ENUM_NEXT(payload_type_short_names, HEADER, CONFIGURATION_ATTRIBUTE, EXTENSIBLE_AUTHENTICATION,
|
||||
ENUM_NEXT(payload_type_short_names, HEADER, ENCRYPTED_V1, EXTENSIBLE_AUTHENTICATION,
|
||||
"HDR",
|
||||
"PROP",
|
||||
"PROP",
|
||||
"TRANS",
|
||||
"TRANS",
|
||||
"TRANSATTR",
|
||||
"TRANSATTR",
|
||||
"TSSUB",
|
||||
"CPATTR");
|
||||
"CATTR",
|
||||
"CATTR",
|
||||
"E");
|
||||
#endif /* ME */
|
||||
ENUM_END(payload_type_short_names, CONFIGURATION_ATTRIBUTE);
|
||||
ENUM_END(payload_type_short_names, ENCRYPTED_V1);
|
||||
|
||||
/*
|
||||
* see header
|
||||
|
@ -128,29 +185,36 @@ payload_t *payload_create(payload_type_t type)
|
|||
case HEADER:
|
||||
return (payload_t*)ike_header_create();
|
||||
case SECURITY_ASSOCIATION:
|
||||
return (payload_t*)sa_payload_create();
|
||||
case SECURITY_ASSOCIATION_V1:
|
||||
return (payload_t*)sa_payload_create(type);
|
||||
case PROPOSAL_SUBSTRUCTURE:
|
||||
return (payload_t*)proposal_substructure_create();
|
||||
case PROPOSAL_SUBSTRUCTURE_V1:
|
||||
return (payload_t*)proposal_substructure_create(type);
|
||||
case TRANSFORM_SUBSTRUCTURE:
|
||||
return (payload_t*)transform_substructure_create();
|
||||
case TRANSFORM_SUBSTRUCTURE_V1:
|
||||
return (payload_t*)transform_substructure_create(type);
|
||||
case TRANSFORM_ATTRIBUTE:
|
||||
return (payload_t*)transform_attribute_create();
|
||||
case TRANSFORM_ATTRIBUTE_V1:
|
||||
return (payload_t*)transform_attribute_create(type);
|
||||
case NONCE:
|
||||
return (payload_t*)nonce_payload_create();
|
||||
case NONCE_V1:
|
||||
return (payload_t*)nonce_payload_create(type);
|
||||
case ID_INITIATOR:
|
||||
return (payload_t*)id_payload_create(ID_INITIATOR);
|
||||
case ID_RESPONDER:
|
||||
return (payload_t*)id_payload_create(ID_RESPONDER);
|
||||
case ID_V1:
|
||||
case NAT_OA_V1:
|
||||
#ifdef ME
|
||||
case ID_PEER:
|
||||
return (payload_t*)id_payload_create(ID_PEER);
|
||||
#endif /* ME */
|
||||
return (payload_t*)id_payload_create(type);
|
||||
case AUTHENTICATION:
|
||||
return (payload_t*)auth_payload_create();
|
||||
case CERTIFICATE:
|
||||
return (payload_t*)cert_payload_create();
|
||||
case CERTIFICATE_V1:
|
||||
return (payload_t*)cert_payload_create(type);
|
||||
case CERTIFICATE_REQUEST:
|
||||
return (payload_t*)certreq_payload_create();
|
||||
case CERTIFICATE_REQUEST_V1:
|
||||
return (payload_t*)certreq_payload_create(type);
|
||||
case TRAFFIC_SELECTOR_SUBSTRUCTURE:
|
||||
return (payload_t*)traffic_selector_substructure_create();
|
||||
case TRAFFIC_SELECTOR_INITIATOR:
|
||||
|
@ -158,21 +222,32 @@ payload_t *payload_create(payload_type_t type)
|
|||
case TRAFFIC_SELECTOR_RESPONDER:
|
||||
return (payload_t*)ts_payload_create(FALSE);
|
||||
case KEY_EXCHANGE:
|
||||
return (payload_t*)ke_payload_create();
|
||||
case KEY_EXCHANGE_V1:
|
||||
return (payload_t*)ke_payload_create(type);
|
||||
case NOTIFY:
|
||||
return (payload_t*)notify_payload_create();
|
||||
case NOTIFY_V1:
|
||||
return (payload_t*)notify_payload_create(type);
|
||||
case DELETE:
|
||||
return (payload_t*)delete_payload_create(0);
|
||||
case DELETE_V1:
|
||||
return (payload_t*)delete_payload_create(type, 0);
|
||||
case VENDOR_ID:
|
||||
return (payload_t*)vendor_id_payload_create();
|
||||
case VENDOR_ID_V1:
|
||||
return (payload_t*)vendor_id_payload_create(type);
|
||||
case HASH_V1:
|
||||
case SIGNATURE_V1:
|
||||
case NAT_D_V1:
|
||||
return (payload_t*)hash_payload_create(type);
|
||||
case CONFIGURATION:
|
||||
return (payload_t*)cp_payload_create();
|
||||
case CONFIGURATION_V1:
|
||||
return (payload_t*)cp_payload_create(type);
|
||||
case CONFIGURATION_ATTRIBUTE:
|
||||
return (payload_t*)configuration_attribute_create();
|
||||
case CONFIGURATION_ATTRIBUTE_V1:
|
||||
return (payload_t*)configuration_attribute_create(type);
|
||||
case EXTENSIBLE_AUTHENTICATION:
|
||||
return (payload_t*)eap_payload_create();
|
||||
case ENCRYPTED:
|
||||
return (payload_t*)encryption_payload_create();
|
||||
case ENCRYPTED_V1:
|
||||
return (payload_t*)encryption_payload_create(type);
|
||||
default:
|
||||
return (payload_t*)unknown_payload_create(type);
|
||||
}
|
||||
|
@ -183,8 +258,19 @@ payload_t *payload_create(payload_type_t type)
|
|||
*/
|
||||
bool payload_is_known(payload_type_t type)
|
||||
{
|
||||
if (type == HEADER ||
|
||||
(type >= SECURITY_ASSOCIATION && type <= EXTENSIBLE_AUTHENTICATION))
|
||||
if (type == HEADER)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
if (type >= SECURITY_ASSOCIATION && type <= EXTENSIBLE_AUTHENTICATION)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
if (type >= SECURITY_ASSOCIATION_V1 && type <= CONFIGURATION_V1)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
if (type >= NAT_D_V1 && type <= NAT_OA_V1)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -203,10 +289,9 @@ bool payload_is_known(payload_type_t type)
|
|||
void* payload_get_field(payload_t *payload, encoding_type_t type, u_int skip)
|
||||
{
|
||||
encoding_rule_t *rule;
|
||||
size_t count;
|
||||
int i;
|
||||
int i, count;
|
||||
|
||||
payload->get_encoding_rules(payload, &rule, &count);
|
||||
count = payload->get_encoding_rules(payload, &rule);
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if (rule[i].type == type && skip-- == 0)
|
||||
|
|
|
@ -29,20 +29,104 @@ typedef struct payload_t payload_t;
|
|||
#include <library.h>
|
||||
#include <encoding/payloads/encodings.h>
|
||||
|
||||
/**
|
||||
* Domain of interpretation used by IPsec/IKEv1
|
||||
*/
|
||||
#define IKEV1_DOI_IPSEC 1
|
||||
|
||||
/**
|
||||
* Payload-Types of a IKEv2-Message.
|
||||
* Payload-Types of an IKE message.
|
||||
*
|
||||
* Header and substructures are also defined as
|
||||
* payload types with values from PRIVATE USE space.
|
||||
*/
|
||||
enum payload_type_t{
|
||||
enum payload_type_t {
|
||||
|
||||
/**
|
||||
* End of payload list in next_payload
|
||||
*/
|
||||
NO_PAYLOAD = 0,
|
||||
|
||||
/**
|
||||
* The security association (SA) payload containing proposals.
|
||||
*/
|
||||
SECURITY_ASSOCIATION_V1 = 1,
|
||||
|
||||
/**
|
||||
* The proposal payload, containing transforms.
|
||||
*/
|
||||
PROPOSAL_V1 = 2,
|
||||
|
||||
/**
|
||||
* The transform payload.
|
||||
*/
|
||||
TRANSFORM_V1 = 3,
|
||||
|
||||
/**
|
||||
* The key exchange (KE) payload containing diffie-hellman values.
|
||||
*/
|
||||
KEY_EXCHANGE_V1 = 4,
|
||||
|
||||
/**
|
||||
* ID payload.
|
||||
*/
|
||||
ID_V1 = 5,
|
||||
|
||||
/**
|
||||
* Certificate payload with certificates (CERT).
|
||||
*/
|
||||
CERTIFICATE_V1 = 6,
|
||||
|
||||
/**
|
||||
* Certificate request payload.
|
||||
*/
|
||||
CERTIFICATE_REQUEST_V1 = 7,
|
||||
|
||||
/**
|
||||
* Hash payload.
|
||||
*/
|
||||
HASH_V1 = 8,
|
||||
|
||||
/**
|
||||
* Signature payload
|
||||
*/
|
||||
SIGNATURE_V1 = 9,
|
||||
|
||||
/**
|
||||
* Nonce payload.
|
||||
*/
|
||||
NONCE_V1 = 10,
|
||||
|
||||
/**
|
||||
* Notification payload.
|
||||
*/
|
||||
NOTIFY_V1 = 11,
|
||||
|
||||
/**
|
||||
* Delete payload.
|
||||
*/
|
||||
DELETE_V1 = 12,
|
||||
|
||||
/**
|
||||
* Vendor id payload.
|
||||
*/
|
||||
VENDOR_ID_V1 = 13,
|
||||
|
||||
/**
|
||||
* Attribute payload (ISAKMP Mode Config, aka configuration payload.
|
||||
*/
|
||||
CONFIGURATION_V1 = 14,
|
||||
|
||||
/**
|
||||
* NAT discovery payload (NAT-D).
|
||||
*/
|
||||
NAT_D_V1 = 20,
|
||||
|
||||
/**
|
||||
* NAT original address payload (NAT-OA)
|
||||
*/
|
||||
NAT_OA_V1 = 21,
|
||||
|
||||
/**
|
||||
* The security association (SA) payload containing proposals.
|
||||
*/
|
||||
|
@ -134,50 +218,60 @@ enum payload_type_t{
|
|||
/**
|
||||
* Header has a value of PRIVATE USE space.
|
||||
*
|
||||
* This payload type is not sent over wire and just
|
||||
* used internally to handle IKEv2-Header like a payload.
|
||||
* This type and all the following are never sent over wire and are
|
||||
* used internally only.
|
||||
*/
|
||||
HEADER = 256,
|
||||
|
||||
/**
|
||||
* PROPOSAL_SUBSTRUCTURE has a value of PRIVATE USE space.
|
||||
*
|
||||
* This payload type is not sent over wire and just
|
||||
* used internally to handle a proposal substructure like a payload.
|
||||
* PROPOSAL_SUBSTRUCTURE, IKEv2 proposals in a SA payload.
|
||||
*/
|
||||
PROPOSAL_SUBSTRUCTURE = 257,
|
||||
PROPOSAL_SUBSTRUCTURE,
|
||||
|
||||
/**
|
||||
* TRANSFORM_SUBSTRUCTURE has a value of PRIVATE USE space.
|
||||
*
|
||||
* This payload type is not sent over wire and just
|
||||
* used internally to handle a transform substructure like a payload.
|
||||
* PROPOSAL_SUBSTRUCTURE_V1, IKEv1 proposals in a SA payload.
|
||||
*/
|
||||
TRANSFORM_SUBSTRUCTURE = 258,
|
||||
PROPOSAL_SUBSTRUCTURE_V1,
|
||||
|
||||
/**
|
||||
* TRANSFORM_ATTRIBUTE has a value of PRIVATE USE space.
|
||||
*
|
||||
* This payload type is not sent over wire and just
|
||||
* used internally to handle a transform attribute like a payload.
|
||||
* TRANSFORM_SUBSTRUCTURE, IKEv2 transforms in a proposal substructure.
|
||||
*/
|
||||
TRANSFORM_ATTRIBUTE = 259,
|
||||
TRANSFORM_SUBSTRUCTURE,
|
||||
|
||||
/**
|
||||
* TRAFFIC_SELECTOR_SUBSTRUCTURE has a value of PRIVATE USE space.
|
||||
*
|
||||
* This payload type is not sent over wire and just
|
||||
* used internally to handle a transform selector like a payload.
|
||||
* TRANSFORM_SUBSTRUCTURE_V1, IKEv1 transforms in a proposal substructure.
|
||||
*/
|
||||
TRAFFIC_SELECTOR_SUBSTRUCTURE = 260,
|
||||
TRANSFORM_SUBSTRUCTURE_V1,
|
||||
|
||||
/**
|
||||
* CONFIGURATION_ATTRIBUTE has a value of PRIVATE USE space.
|
||||
*
|
||||
* This payload type is not sent over wire and just
|
||||
* used internally to handle a transform attribute like a payload.
|
||||
* TRANSFORM_ATTRIBUTE, IKEv2 attribute in a transform.
|
||||
*/
|
||||
CONFIGURATION_ATTRIBUTE = 261,
|
||||
TRANSFORM_ATTRIBUTE,
|
||||
|
||||
/**
|
||||
* TRANSFORM_ATTRIBUTE_V1, IKEv1 attribute in a transform.
|
||||
*/
|
||||
TRANSFORM_ATTRIBUTE_V1,
|
||||
|
||||
/**
|
||||
* TRAFFIC_SELECTOR_SUBSTRUCTURE, traffic selector in a TS payload.
|
||||
*/
|
||||
TRAFFIC_SELECTOR_SUBSTRUCTURE,
|
||||
|
||||
/**
|
||||
* CONFIGURATION_ATTRIBUTE, IKEv2 attribute in a configuration payload.
|
||||
*/
|
||||
CONFIGURATION_ATTRIBUTE,
|
||||
|
||||
/**
|
||||
* CONFIGURATION_ATTRIBUTE_V1, IKEv1 attribute in a configuration payload.
|
||||
*/
|
||||
CONFIGURATION_ATTRIBUTE_V1,
|
||||
|
||||
/**
|
||||
* This is not really a payload, but rather the complete IKEv1 message.
|
||||
*/
|
||||
ENCRYPTED_V1,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -202,43 +296,50 @@ struct payload_t {
|
|||
/**
|
||||
* Get encoding rules for this payload.
|
||||
*
|
||||
* @param rules location to store pointer of first rule
|
||||
* @param rule_count location to store number of rules
|
||||
* @param rules location to store pointer to rules
|
||||
* @return number of rules
|
||||
*/
|
||||
void (*get_encoding_rules) (payload_t *this, encoding_rule_t **rules, size_t *rule_count);
|
||||
int (*get_encoding_rules) (payload_t *this, encoding_rule_t **rules);
|
||||
|
||||
/**
|
||||
* Get non-variable header length for a variable length payload.
|
||||
*
|
||||
* @return fixed length of the payload
|
||||
*/
|
||||
int (*get_header_length)(payload_t *this);
|
||||
|
||||
/**
|
||||
* Get type of payload.
|
||||
*
|
||||
* @return type of this payload
|
||||
* @return type of this payload
|
||||
*/
|
||||
payload_type_t (*get_type) (payload_t *this);
|
||||
|
||||
/**
|
||||
* Get type of next payload or NO_PAYLOAD (0) if this is the last one.
|
||||
*
|
||||
* @return type of next payload
|
||||
* @return type of next payload
|
||||
*/
|
||||
payload_type_t (*get_next_type) (payload_t *this);
|
||||
|
||||
/**
|
||||
* Set type of next payload.
|
||||
*
|
||||
* @param type type of next payload
|
||||
* @param type type of next payload
|
||||
*/
|
||||
void (*set_next_type) (payload_t *this,payload_type_t type);
|
||||
|
||||
/**
|
||||
* Get length of payload.
|
||||
*
|
||||
* @return length of this payload
|
||||
* @return length of this payload
|
||||
*/
|
||||
size_t (*get_length) (payload_t *this);
|
||||
|
||||
/**
|
||||
* Verifies payload structure and makes consistence check.
|
||||
*
|
||||
* @return SUCCESS, FAILED if consistence not given
|
||||
* @return SUCCESS, FAILED if consistence not given
|
||||
*/
|
||||
status_t (*verify) (payload_t *this);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -29,17 +29,11 @@ typedef struct proposal_substructure_t proposal_substructure_t;
|
|||
#include <encoding/payloads/transform_substructure.h>
|
||||
#include <config/proposal.h>
|
||||
#include <utils/linked_list.h>
|
||||
|
||||
#include <kernel/kernel_ipsec.h>
|
||||
#include <sa/authenticator.h>
|
||||
|
||||
/**
|
||||
* Length of the proposal substructure header (without spi).
|
||||
*/
|
||||
#define PROPOSAL_SUBSTRUCTURE_HEADER_LENGTH 8
|
||||
|
||||
/**
|
||||
* Class representing an IKEv2-PROPOSAL SUBSTRUCTURE.
|
||||
*
|
||||
* The PROPOSAL SUBSTRUCTURE format is described in RFC section 3.3.1.
|
||||
* Class representing an IKEv1/IKEv2 proposal substructure.
|
||||
*/
|
||||
struct proposal_substructure_t {
|
||||
|
||||
|
@ -104,11 +98,11 @@ struct proposal_substructure_t {
|
|||
void (*set_spi) (proposal_substructure_t *this, chunk_t spi);
|
||||
|
||||
/**
|
||||
* Get a proposal_t from the propsal_substructure_t.
|
||||
* Get proposals contained in a propsal_substructure_t.
|
||||
*
|
||||
* @return proposal_t
|
||||
* @param list list to add created proposals to
|
||||
*/
|
||||
proposal_t * (*get_proposal) (proposal_substructure_t *this);
|
||||
void (*get_proposals) (proposal_substructure_t *this, linked_list_t *list);
|
||||
|
||||
/**
|
||||
* Create an enumerator over transform substructures.
|
||||
|
@ -117,6 +111,35 @@ struct proposal_substructure_t {
|
|||
*/
|
||||
enumerator_t* (*create_substructure_enumerator)(proposal_substructure_t *this);
|
||||
|
||||
/**
|
||||
* Get the (shortest) lifetime of a proposal (IKEv1 only).
|
||||
*
|
||||
* @return lifetime, in seconds
|
||||
*/
|
||||
u_int32_t (*get_lifetime)(proposal_substructure_t *this);
|
||||
|
||||
/**
|
||||
* Get the (shortest) life duration of a proposal (IKEv1 only).
|
||||
*
|
||||
* @return life duration, in bytes
|
||||
*/
|
||||
u_int64_t (*get_lifebytes)(proposal_substructure_t *this);
|
||||
|
||||
/**
|
||||
* Get the first authentication method from the proposal (IKEv1 only).
|
||||
*
|
||||
* @return auth method, or AUTH_NONE
|
||||
*/
|
||||
auth_method_t (*get_auth_method)(proposal_substructure_t *this);
|
||||
|
||||
/**
|
||||
* Get the (first) encapsulation mode from a proposal (IKEv1 only).
|
||||
*
|
||||
* @param udp set to TRUE if UDP encapsulation used
|
||||
* @return ipsec encapsulation mode
|
||||
*/
|
||||
ipsec_mode_t (*get_encap_mode)(proposal_substructure_t *this, bool *udp);
|
||||
|
||||
/**
|
||||
* Destroys an proposal_substructure_t object.
|
||||
*/
|
||||
|
@ -126,17 +149,49 @@ struct proposal_substructure_t {
|
|||
/**
|
||||
* Creates an empty proposal_substructure_t object
|
||||
*
|
||||
* @return proposal_substructure_t object
|
||||
* @param type PROPOSAL_SUBSTRUCTURE or PROPOSAL_SUBSTRUCTURE_V1
|
||||
* @return proposal_substructure_t object
|
||||
*/
|
||||
proposal_substructure_t *proposal_substructure_create(void);
|
||||
proposal_substructure_t *proposal_substructure_create(payload_type_t type);
|
||||
|
||||
/**
|
||||
* Creates a proposal_substructure_t from a proposal_t.
|
||||
* Creates an IKEv2 proposal_substructure_t from a proposal_t.
|
||||
*
|
||||
* @param proposal proposal to build a substruct out of it
|
||||
* @return proposal_substructure_t object
|
||||
* @param proposal proposal to build a substruct out of it
|
||||
* @return proposal_substructure_t PROPOSAL_SUBSTRUCTURE
|
||||
*/
|
||||
proposal_substructure_t *proposal_substructure_create_from_proposal(
|
||||
proposal_substructure_t *proposal_substructure_create_from_proposal_v2(
|
||||
proposal_t *proposal);
|
||||
/**
|
||||
* Creates an IKEv1 proposal_substructure_t from a proposal_t.
|
||||
*
|
||||
* @param proposal proposal to build a substruct out of it
|
||||
* @param lifetime lifetime in seconds
|
||||
* @param lifebytes lifebytes, in bytes
|
||||
* @param auth authentication method to use, or AUTH_NONE
|
||||
* @param mode IPsec encapsulation mode, TRANSPORT or TUNNEL
|
||||
* @param udp TRUE to use UDP encapsulation
|
||||
*
|
||||
*
|
||||
* @return proposal_substructure_t object PROPOSAL_SUBSTRUCTURE_V1
|
||||
*/
|
||||
proposal_substructure_t *proposal_substructure_create_from_proposal_v1(
|
||||
proposal_t *proposal, u_int32_t lifetime, u_int64_t lifebytes,
|
||||
auth_method_t auth, ipsec_mode_t mode, bool udp);
|
||||
|
||||
/**
|
||||
* Creates an IKEv1 proposal_substructure_t from a list of proposal_t.
|
||||
*
|
||||
* @param proposals list of proposal_t to encode in a substructure
|
||||
* @param lifetime lifetime in seconds
|
||||
* @param lifebytes lifebytes, in bytes
|
||||
* @param auth authentication method to use, or AUTH_NONE
|
||||
* @param mode IPsec encapsulation mode, TRANSPORT or TUNNEL
|
||||
* @param udp TRUE to use UDP encapsulation
|
||||
* @return IKEv1 proposal_substructure_t PROPOSAL_SUBSTRUCTURE_V1
|
||||
*/
|
||||
proposal_substructure_t *proposal_substructure_create_from_proposals_v1(
|
||||
linked_list_t *proposals, u_int32_t lifetime, u_int64_t lifebytes,
|
||||
auth_method_t auth, ipsec_mode_t mode, bool udp);
|
||||
|
||||
#endif /** PROPOSAL_SUBSTRUCTURE_H_ @}*/
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
#include <utils/linked_list.h>
|
||||
#include <daemon.h>
|
||||
|
||||
/* IKEv1 situation */
|
||||
#define SIT_IDENTITY_ONLY 1
|
||||
|
||||
typedef struct private_sa_payload_t private_sa_payload_t;
|
||||
|
||||
|
@ -48,7 +50,7 @@ struct private_sa_payload_t {
|
|||
/**
|
||||
* Reserved bits
|
||||
*/
|
||||
bool reserved[7];
|
||||
bool reserved[8];
|
||||
|
||||
/**
|
||||
* Length of this payload.
|
||||
|
@ -58,21 +60,75 @@ struct private_sa_payload_t {
|
|||
/**
|
||||
* Proposals in this payload are stored in a linked_list_t.
|
||||
*/
|
||||
linked_list_t * proposals;
|
||||
linked_list_t *proposals;
|
||||
|
||||
/**
|
||||
* Type of this payload, V1 or V2
|
||||
*/
|
||||
payload_type_t type;
|
||||
|
||||
/**
|
||||
* IKEv1 DOI
|
||||
*/
|
||||
u_int32_t doi;
|
||||
|
||||
/**
|
||||
* IKEv1 situation
|
||||
*/
|
||||
u_int32_t situation;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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 rules for IKEv1 SA payload
|
||||
*/
|
||||
encoding_rule_t sa_payload_encodings[] = {
|
||||
static encoding_rule_t encodings_v1[] = {
|
||||
/* 1 Byte next payload type, stored in the field next_payload */
|
||||
{ U_INT_8, offsetof(private_sa_payload_t, next_payload) },
|
||||
/* 8 reserved bits */
|
||||
{ RESERVED_BIT, offsetof(private_sa_payload_t, reserved[0]) },
|
||||
{ RESERVED_BIT, offsetof(private_sa_payload_t, reserved[1]) },
|
||||
{ RESERVED_BIT, offsetof(private_sa_payload_t, reserved[2]) },
|
||||
{ RESERVED_BIT, offsetof(private_sa_payload_t, reserved[3]) },
|
||||
{ RESERVED_BIT, offsetof(private_sa_payload_t, reserved[4]) },
|
||||
{ RESERVED_BIT, offsetof(private_sa_payload_t, reserved[5]) },
|
||||
{ RESERVED_BIT, offsetof(private_sa_payload_t, reserved[6]) },
|
||||
{ RESERVED_BIT, offsetof(private_sa_payload_t, reserved[7]) },
|
||||
/* Length of the whole SA payload*/
|
||||
{ PAYLOAD_LENGTH, offsetof(private_sa_payload_t, payload_length) },
|
||||
/* DOI*/
|
||||
{ U_INT_32, offsetof(private_sa_payload_t, doi) },
|
||||
/* Situation*/
|
||||
{ U_INT_32, offsetof(private_sa_payload_t, situation) },
|
||||
/* Proposals are stored in a proposal substructure list */
|
||||
{ PAYLOAD_LIST + PROPOSAL_SUBSTRUCTURE_V1,
|
||||
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 ! RESERVED ! Payload Length !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! DOI !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! Situation !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! !
|
||||
~ <Proposals> ~
|
||||
! !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
/**
|
||||
* Encoding rules for IKEv2 SA payload
|
||||
*/
|
||||
static encoding_rule_t encodings_v2[] = {
|
||||
/* 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 */
|
||||
/* 7 Bit reserved bits */
|
||||
{ RESERVED_BIT, offsetof(private_sa_payload_t, reserved[0]) },
|
||||
{ RESERVED_BIT, offsetof(private_sa_payload_t, reserved[1]) },
|
||||
{ RESERVED_BIT, offsetof(private_sa_payload_t, reserved[2]) },
|
||||
|
@ -82,9 +138,9 @@ encoding_rule_t sa_payload_encodings[] = {
|
|||
{ RESERVED_BIT, offsetof(private_sa_payload_t, reserved[6]) },
|
||||
/* 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) },
|
||||
/* Proposals are stored in a proposal substructure list */
|
||||
{ PAYLOAD_LIST + PROPOSAL_SUBSTRUCTURE,
|
||||
offsetof(private_sa_payload_t, proposals) },
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -102,11 +158,16 @@ encoding_rule_t sa_payload_encodings[] = {
|
|||
METHOD(payload_t, verify, status_t,
|
||||
private_sa_payload_t *this)
|
||||
{
|
||||
int expected_number = 1, current_number;
|
||||
int expected_number = 0, current_number;
|
||||
status_t status = SUCCESS;
|
||||
enumerator_t *enumerator;
|
||||
proposal_substructure_t *substruct;
|
||||
|
||||
if (this->type == SECURITY_ASSOCIATION)
|
||||
{
|
||||
expected_number = 1;
|
||||
}
|
||||
|
||||
/* check proposal numbering */
|
||||
enumerator = this->proposals->create_enumerator(this->proposals);
|
||||
while (enumerator->enumerate(enumerator, (void**)&substruct))
|
||||
|
@ -131,17 +192,32 @@ METHOD(payload_t, verify, status_t,
|
|||
return status;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_encoding_rules, void,
|
||||
private_sa_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
|
||||
METHOD(payload_t, get_encoding_rules, int,
|
||||
private_sa_payload_t *this, encoding_rule_t **rules)
|
||||
{
|
||||
*rules = sa_payload_encodings;
|
||||
*rule_count = countof(sa_payload_encodings);
|
||||
if (this->type == SECURITY_ASSOCIATION_V1)
|
||||
{
|
||||
*rules = encodings_v1;
|
||||
return countof(encodings_v1);
|
||||
}
|
||||
*rules = encodings_v2;
|
||||
return countof(encodings_v2);
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_header_length, int,
|
||||
private_sa_payload_t *this)
|
||||
{
|
||||
if (this->type == SECURITY_ASSOCIATION_V1)
|
||||
{
|
||||
return 12;
|
||||
}
|
||||
return 4;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_type, payload_type_t,
|
||||
private_sa_payload_t *this)
|
||||
{
|
||||
return SECURITY_ASSOCIATION;
|
||||
return this->type;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_next_type, payload_type_t,
|
||||
|
@ -163,16 +239,15 @@ static void compute_length(private_sa_payload_t *this)
|
|||
{
|
||||
enumerator_t *enumerator;
|
||||
payload_t *current;
|
||||
size_t length = SA_PAYLOAD_HEADER_LENGTH;
|
||||
|
||||
this->payload_length = get_header_length(this);
|
||||
|
||||
enumerator = this->proposals->create_enumerator(this->proposals);
|
||||
while (enumerator->enumerate(enumerator, (void **)¤t))
|
||||
{
|
||||
length += current->get_length(current);
|
||||
this->payload_length += current->get_length(current);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
this->payload_length = length;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_length, size_t,
|
||||
|
@ -181,14 +256,16 @@ METHOD(payload_t, get_length, size_t,
|
|||
return this->payload_length;
|
||||
}
|
||||
|
||||
METHOD(sa_payload_t, add_proposal, void,
|
||||
private_sa_payload_t *this, proposal_t *proposal)
|
||||
/**
|
||||
* Create a transform substructure from a proposal, add to payload
|
||||
*/
|
||||
static void add_proposal_v2(private_sa_payload_t *this, proposal_t *proposal)
|
||||
{
|
||||
proposal_substructure_t *substruct, *last;
|
||||
u_int count;
|
||||
|
||||
substruct = proposal_substructure_create_from_proposal_v2(proposal);
|
||||
count = this->proposals->get_count(this->proposals);
|
||||
substruct = proposal_substructure_create_from_proposal(proposal);
|
||||
if (count > 0)
|
||||
{
|
||||
this->proposals->get_last(this->proposals, (void**)&last);
|
||||
|
@ -215,8 +292,13 @@ METHOD(sa_payload_t, get_proposals, linked_list_t*,
|
|||
int ignore_struct_number = 0;
|
||||
enumerator_t *enumerator;
|
||||
proposal_substructure_t *substruct;
|
||||
linked_list_t *list;
|
||||
proposal_t *proposal;
|
||||
linked_list_t *list;
|
||||
|
||||
if (this->type == SECURITY_ASSOCIATION_V1)
|
||||
{ /* IKEv1 proposals start with 0 */
|
||||
struct_number = ignore_struct_number = -1;
|
||||
}
|
||||
|
||||
list = linked_list_create();
|
||||
/* we do not support proposals split up to two proposal substructures, as
|
||||
|
@ -233,18 +315,16 @@ METHOD(sa_payload_t, get_proposals, linked_list_t*,
|
|||
if (ignore_struct_number < struct_number)
|
||||
{
|
||||
/* remove an already added, if first of series */
|
||||
list->remove_last(list, (void**)&proposal);
|
||||
proposal->destroy(proposal);
|
||||
if (list->remove_last(list, (void**)&proposal) == SUCCESS)
|
||||
{
|
||||
proposal->destroy(proposal);
|
||||
}
|
||||
ignore_struct_number = struct_number;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
struct_number++;
|
||||
proposal = substruct->get_proposal(substruct);
|
||||
if (proposal)
|
||||
{
|
||||
list->insert_last(list, proposal);
|
||||
}
|
||||
substruct->get_proposals(substruct, list);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
return list;
|
||||
|
@ -256,18 +336,86 @@ METHOD(sa_payload_t, create_substructure_enumerator, enumerator_t*,
|
|||
return this->proposals->create_enumerator(this->proposals);
|
||||
}
|
||||
|
||||
METHOD(sa_payload_t, get_lifetime, u_int32_t,
|
||||
private_sa_payload_t *this)
|
||||
{
|
||||
proposal_substructure_t *substruct;
|
||||
enumerator_t *enumerator;
|
||||
u_int32_t lifetime = 0;
|
||||
|
||||
enumerator = this->proposals->create_enumerator(this->proposals);
|
||||
if (enumerator->enumerate(enumerator, &substruct))
|
||||
{
|
||||
lifetime = substruct->get_lifetime(substruct);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
return lifetime;
|
||||
}
|
||||
|
||||
METHOD(sa_payload_t, get_lifebytes, u_int64_t,
|
||||
private_sa_payload_t *this)
|
||||
{
|
||||
proposal_substructure_t *substruct;
|
||||
enumerator_t *enumerator;
|
||||
u_int64_t lifebytes = 0;
|
||||
|
||||
enumerator = this->proposals->create_enumerator(this->proposals);
|
||||
if (enumerator->enumerate(enumerator, &substruct))
|
||||
{
|
||||
lifebytes = substruct->get_lifebytes(substruct);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
return lifebytes;
|
||||
}
|
||||
|
||||
METHOD(sa_payload_t, get_auth_method, auth_method_t,
|
||||
private_sa_payload_t *this)
|
||||
{
|
||||
proposal_substructure_t *substruct;
|
||||
enumerator_t *enumerator;
|
||||
auth_method_t method = AUTH_NONE;
|
||||
|
||||
enumerator = this->proposals->create_enumerator(this->proposals);
|
||||
if (enumerator->enumerate(enumerator, &substruct))
|
||||
{
|
||||
method = substruct->get_auth_method(substruct);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
return method;
|
||||
}
|
||||
|
||||
METHOD(sa_payload_t, get_encap_mode, ipsec_mode_t,
|
||||
private_sa_payload_t *this, bool *udp)
|
||||
{
|
||||
proposal_substructure_t *substruct;
|
||||
enumerator_t *enumerator;
|
||||
ipsec_mode_t mode = MODE_NONE;
|
||||
|
||||
enumerator = this->proposals->create_enumerator(this->proposals);
|
||||
if (enumerator->enumerate(enumerator, &substruct))
|
||||
{
|
||||
mode = substruct->get_encap_mode(substruct, udp);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
return mode;
|
||||
}
|
||||
|
||||
METHOD2(payload_t, sa_payload_t, destroy, void,
|
||||
private_sa_payload_t *this)
|
||||
{
|
||||
this->proposals->destroy_offset(this->proposals,
|
||||
offsetof(proposal_substructure_t, destroy));
|
||||
offsetof(payload_t, destroy));
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
sa_payload_t *sa_payload_create()
|
||||
sa_payload_t *sa_payload_create(payload_type_t type)
|
||||
{
|
||||
private_sa_payload_t *this;
|
||||
|
||||
|
@ -276,38 +424,48 @@ sa_payload_t *sa_payload_create()
|
|||
.payload_interface = {
|
||||
.verify = _verify,
|
||||
.get_encoding_rules = _get_encoding_rules,
|
||||
.get_header_length = _get_header_length,
|
||||
.get_length = _get_length,
|
||||
.get_next_type = _get_next_type,
|
||||
.set_next_type = _set_next_type,
|
||||
.get_type = _get_type,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.add_proposal = _add_proposal,
|
||||
.get_proposals = _get_proposals,
|
||||
.create_substructure_enumerator = _create_substructure_enumerator,
|
||||
.get_lifetime = _get_lifetime,
|
||||
.get_lifebytes = _get_lifebytes,
|
||||
.get_auth_method = _get_auth_method,
|
||||
.get_encap_mode = _get_encap_mode,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.next_payload = NO_PAYLOAD,
|
||||
.payload_length = SA_PAYLOAD_HEADER_LENGTH,
|
||||
.proposals = linked_list_create(),
|
||||
.type = type,
|
||||
/* for IKEv1 only */
|
||||
.doi = IKEV1_DOI_IPSEC,
|
||||
.situation = SIT_IDENTITY_ONLY,
|
||||
);
|
||||
|
||||
compute_length(this);
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
sa_payload_t *sa_payload_create_from_proposal_list(linked_list_t *proposals)
|
||||
sa_payload_t *sa_payload_create_from_proposals_v2(linked_list_t *proposals)
|
||||
{
|
||||
private_sa_payload_t *this;
|
||||
enumerator_t *enumerator;
|
||||
proposal_t *proposal;
|
||||
|
||||
this = (private_sa_payload_t*)sa_payload_create();
|
||||
this = (private_sa_payload_t*)sa_payload_create(SECURITY_ASSOCIATION);
|
||||
enumerator = proposals->create_enumerator(proposals);
|
||||
while (enumerator->enumerate(enumerator, &proposal))
|
||||
{
|
||||
add_proposal(this, proposal);
|
||||
add_proposal_v2(this, proposal);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
|
@ -317,12 +475,57 @@ sa_payload_t *sa_payload_create_from_proposal_list(linked_list_t *proposals)
|
|||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
sa_payload_t *sa_payload_create_from_proposal(proposal_t *proposal)
|
||||
sa_payload_t *sa_payload_create_from_proposal_v2(proposal_t *proposal)
|
||||
{
|
||||
private_sa_payload_t *this;
|
||||
|
||||
this = (private_sa_payload_t*)sa_payload_create();
|
||||
add_proposal(this, proposal);
|
||||
this = (private_sa_payload_t*)sa_payload_create(SECURITY_ASSOCIATION);
|
||||
add_proposal_v2(this, proposal);
|
||||
|
||||
return &this->public;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
sa_payload_t *sa_payload_create_from_proposals_v1(linked_list_t *proposals,
|
||||
u_int32_t lifetime, u_int64_t lifebytes,
|
||||
auth_method_t auth, ipsec_mode_t mode, bool udp)
|
||||
{
|
||||
proposal_substructure_t *substruct;
|
||||
private_sa_payload_t *this;
|
||||
|
||||
this = (private_sa_payload_t*)sa_payload_create(SECURITY_ASSOCIATION_V1);
|
||||
|
||||
/* IKEv1 encodes multiple proposals in a single substructure
|
||||
* TODO-IKEv1: Encode ESP+AH proposals in two different substructs */
|
||||
substruct = proposal_substructure_create_from_proposals_v1(proposals,
|
||||
lifetime, lifebytes, auth, mode, udp);
|
||||
substruct->set_is_last_proposal(substruct, TRUE);
|
||||
this->proposals->insert_last(this->proposals, substruct);
|
||||
compute_length(this);
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
sa_payload_t *sa_payload_create_from_proposal_v1(proposal_t *proposal,
|
||||
u_int32_t lifetime, u_int64_t lifebytes,
|
||||
auth_method_t auth, ipsec_mode_t mode, bool udp)
|
||||
{
|
||||
proposal_substructure_t *substruct;
|
||||
private_sa_payload_t *this;
|
||||
|
||||
this = (private_sa_payload_t*)sa_payload_create(SECURITY_ASSOCIATION_V1);
|
||||
|
||||
substruct = proposal_substructure_create_from_proposal_v1(proposal,
|
||||
lifetime, lifebytes, auth, mode, udp);
|
||||
substruct->set_is_last_proposal(substruct, TRUE);
|
||||
this->proposals->insert_last(this->proposals, substruct);
|
||||
compute_length(this);
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
|
|
@ -28,14 +28,11 @@ typedef struct sa_payload_t sa_payload_t;
|
|||
#include <encoding/payloads/payload.h>
|
||||
#include <encoding/payloads/proposal_substructure.h>
|
||||
#include <utils/linked_list.h>
|
||||
#include <kernel/kernel_ipsec.h>
|
||||
#include <sa/authenticator.h>
|
||||
|
||||
/**
|
||||
* SA_PAYLOAD length in bytes without any proposal substructure.
|
||||
*/
|
||||
#define SA_PAYLOAD_HEADER_LENGTH 4
|
||||
|
||||
/**
|
||||
* Class representing an IKEv2-SA Payload.
|
||||
* Class representing an IKEv1 or IKEv2 SA Payload.
|
||||
*
|
||||
* The SA Payload format is described in RFC section 3.3.
|
||||
*/
|
||||
|
@ -54,11 +51,33 @@ struct sa_payload_t {
|
|||
linked_list_t *(*get_proposals) (sa_payload_t *this);
|
||||
|
||||
/**
|
||||
* Add a child proposal (AH/ESP) to the payload.
|
||||
* Get the (shortest) lifetime of a proposal (IKEv1 only).
|
||||
*
|
||||
* @param proposal child proposal to add to the payload
|
||||
* @return lifetime, in seconds
|
||||
*/
|
||||
void (*add_proposal) (sa_payload_t *this, proposal_t *proposal);
|
||||
u_int32_t (*get_lifetime)(sa_payload_t *this);
|
||||
|
||||
/**
|
||||
* Get the (shortest) life duration of a proposal (IKEv1 only).
|
||||
*
|
||||
* @return life duration, in bytes
|
||||
*/
|
||||
u_int64_t (*get_lifebytes)(sa_payload_t *this);
|
||||
|
||||
/**
|
||||
* Get the first authentication method from the proposal (IKEv1 only).
|
||||
*
|
||||
* @return auth method, or AUTH_NONE
|
||||
*/
|
||||
auth_method_t (*get_auth_method)(sa_payload_t *this);
|
||||
|
||||
/**
|
||||
* Get the (first) encapsulation mode from a proposal (IKEv1 only).
|
||||
*
|
||||
* @param udp set to TRUE if UDP encapsulation used
|
||||
* @return ipsec encapsulation mode
|
||||
*/
|
||||
ipsec_mode_t (*get_encap_mode)(sa_payload_t *this, bool *udp);
|
||||
|
||||
/**
|
||||
* Create an enumerator over all proposal substructures.
|
||||
|
@ -76,27 +95,55 @@ struct sa_payload_t {
|
|||
/**
|
||||
* Creates an empty sa_payload_t object
|
||||
*
|
||||
* @param type SECURITY_ASSOCIATION or SECURITY_ASSOCIATION_V1
|
||||
* @return created sa_payload_t object
|
||||
*/
|
||||
sa_payload_t *sa_payload_create(void);
|
||||
sa_payload_t *sa_payload_create(payload_type_t type);
|
||||
|
||||
/**
|
||||
* Creates a sa_payload_t object from a list of proposals.
|
||||
* Creates an IKEv2 sa_payload_t object from a list of proposals.
|
||||
*
|
||||
* @param proposals list of proposals to build the payload from
|
||||
* @return sa_payload_t object
|
||||
*/
|
||||
sa_payload_t *sa_payload_create_from_proposal_list(linked_list_t *proposals);
|
||||
sa_payload_t *sa_payload_create_from_proposals_v2(linked_list_t *proposals);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* Creates an IKEv2 sa_payload_t object from a single proposal.
|
||||
*
|
||||
* @param proposal proposal from which the payload should be built.
|
||||
* @return sa_payload_t object
|
||||
*/
|
||||
sa_payload_t *sa_payload_create_from_proposal(proposal_t *proposal);
|
||||
sa_payload_t *sa_payload_create_from_proposal_v2(proposal_t *proposal);
|
||||
|
||||
/**
|
||||
* Creates an IKEv1 sa_payload_t object from a list of proposals.
|
||||
*
|
||||
* @param proposals list of proposals to build the payload from
|
||||
* @param lifetime lifetime in seconds
|
||||
* @param lifebytes lifebytes, in bytes
|
||||
* @param auth authentication method to use, or AUTH_NONE
|
||||
* @param mode IPsec encapsulation mode, TRANSPORT or TUNNEL
|
||||
* @param udp TRUE to use UDP encapsulation
|
||||
* @return sa_payload_t object
|
||||
*/
|
||||
sa_payload_t *sa_payload_create_from_proposals_v1(linked_list_t *proposals,
|
||||
u_int32_t lifetime, u_int64_t lifebytes,
|
||||
auth_method_t auth, ipsec_mode_t mode, bool udp);
|
||||
|
||||
/**
|
||||
* Creates an IKEv1 sa_payload_t object from a single proposal.
|
||||
*
|
||||
* @param proposal proposal from which the payload should be built.
|
||||
* @param lifetime lifetime in seconds
|
||||
* @param lifebytes lifebytes, in bytes
|
||||
* @param auth authentication method to use, or AUTH_NONE
|
||||
* @param mode IPsec encapsulation mode, TRANSPORT or TUNNEL
|
||||
* @param udp TRUE to use UDP encapsulation
|
||||
* @return sa_payload_t object
|
||||
*/
|
||||
sa_payload_t *sa_payload_create_from_proposal_v1(proposal_t *proposal,
|
||||
u_int32_t lifetime, u_int64_t lifebytes,
|
||||
auth_method_t auth, ipsec_mode_t mode, bool udp);
|
||||
|
||||
#endif /** SA_PAYLOAD_H_ @}*/
|
||||
|
|
|
@ -74,7 +74,7 @@ struct private_traffic_selector_substructure_t {
|
|||
* The defined offsets are the positions in a object of type
|
||||
* private_traffic_selector_substructure_t.
|
||||
*/
|
||||
encoding_rule_t traffic_selector_substructure_encodings[] = {
|
||||
static encoding_rule_t encodings[] = {
|
||||
/* 1 Byte next ts type*/
|
||||
{ TS_TYPE, offsetof(private_traffic_selector_substructure_t, ts_type) },
|
||||
/* 1 Byte IP protocol id*/
|
||||
|
@ -148,12 +148,17 @@ METHOD(payload_t, verify, status_t,
|
|||
return SUCCESS;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_encoding_rules, void,
|
||||
private_traffic_selector_substructure_t *this, encoding_rule_t **rules,
|
||||
size_t *rule_count)
|
||||
METHOD(payload_t, get_encoding_rules, int,
|
||||
private_traffic_selector_substructure_t *this, encoding_rule_t **rules)
|
||||
{
|
||||
*rules = traffic_selector_substructure_encodings;
|
||||
*rule_count = countof(traffic_selector_substructure_encodings);
|
||||
*rules = encodings;
|
||||
return countof(encodings);
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_header_length, int,
|
||||
private_traffic_selector_substructure_t *this)
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_type, payload_type_t,
|
||||
|
@ -208,6 +213,7 @@ traffic_selector_substructure_t *traffic_selector_substructure_create()
|
|||
.payload_interface = {
|
||||
.verify = _verify,
|
||||
.get_encoding_rules = _get_encoding_rules,
|
||||
.get_header_length = _get_header_length,
|
||||
.get_length = _get_length,
|
||||
.get_next_type = _get_next_type,
|
||||
.set_next_type = _set_next_type,
|
||||
|
@ -217,7 +223,7 @@ traffic_selector_substructure_t *traffic_selector_substructure_create()
|
|||
.get_traffic_selector = _get_traffic_selector,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.payload_length = TRAFFIC_SELECTOR_HEADER_LENGTH,
|
||||
.payload_length = get_header_length(this),
|
||||
/* must be set to be valid */
|
||||
.ts_type = TS_IPV4_ADDR_RANGE,
|
||||
);
|
||||
|
@ -239,7 +245,7 @@ traffic_selector_substructure_t *traffic_selector_substructure_create_from_traff
|
|||
this->end_port = ts->get_to_port(ts);
|
||||
this->starting_address = chunk_clone(ts->get_from_address(ts));
|
||||
this->ending_address = chunk_clone(ts->get_to_address(ts));
|
||||
this->payload_length = TRAFFIC_SELECTOR_HEADER_LENGTH +
|
||||
this->payload_length = get_header_length(this) +
|
||||
this->ending_address.len + this->starting_address.len;
|
||||
|
||||
return &this->public;
|
||||
|
|
|
@ -29,11 +29,6 @@ typedef struct traffic_selector_substructure_t traffic_selector_substructure_t;
|
|||
#include <selectors/traffic_selector.h>
|
||||
#include <encoding/payloads/payload.h>
|
||||
|
||||
/**
|
||||
* Length of a TRAFFIC SELECTOR SUBSTRUCTURE without start and end address.
|
||||
*/
|
||||
#define TRAFFIC_SELECTOR_HEADER_LENGTH 8
|
||||
|
||||
/**
|
||||
* Class representing an IKEv2 TRAFFIC SELECTOR.
|
||||
*
|
||||
|
|
|
@ -23,6 +23,44 @@
|
|||
#include <encoding/payloads/encodings.h>
|
||||
#include <library.h>
|
||||
|
||||
ENUM(tattr_ph1_names, TATTR_PH1_ENCRYPTION_ALGORITHM, TATTR_PH1_GROUP_ORDER,
|
||||
"ENCRYPTION_ALGORITHM",
|
||||
"HASH_ALGORITHM",
|
||||
"AUTH_METHOD",
|
||||
"GROUP",
|
||||
"GROUP_TYPE",
|
||||
"GROUP_PRIME",
|
||||
"GROUP_GENONE",
|
||||
"GROUP_GENTWO",
|
||||
"GROUP_CURVE_A",
|
||||
"GROUP_CURVE_B",
|
||||
"LIFE_TYPE",
|
||||
"LIFE_DURATION",
|
||||
"PRF",
|
||||
"KEY_LENGTH",
|
||||
"FIELD_SIZE",
|
||||
"GROUP_ORDER",
|
||||
);
|
||||
|
||||
ENUM(tattr_ph2_names, TATTR_PH2_SA_LIFE_TYPE, TATTR_PH2_EXT_SEQ_NUMBER,
|
||||
"SA_LIFE_TYPE",
|
||||
"SA_LIFE_DURATION",
|
||||
"GROUP",
|
||||
"ENCAP_MODE",
|
||||
"AUTH_ALGORITHM",
|
||||
"KEY_LENGTH",
|
||||
"KEY_ROUNDS",
|
||||
"COMP_DICT_SIZE",
|
||||
"COMP_PRIV_ALGORITHM",
|
||||
"ECN_TUNNEL",
|
||||
"EXT_SEQ_NUMBER",
|
||||
);
|
||||
|
||||
ENUM(tattr_ikev2_names, TATTR_IKEV2_KEY_LENGTH, TATTR_IKEV2_KEY_LENGTH,
|
||||
"KEY_LENGTH",
|
||||
);
|
||||
|
||||
|
||||
typedef struct private_transform_attribute_t private_transform_attribute_t;
|
||||
|
||||
/**
|
||||
|
@ -57,22 +95,17 @@ struct private_transform_attribute_t {
|
|||
* Attribute value as chunk if attribute_format is 0 (FALSE).
|
||||
*/
|
||||
chunk_t attribute_value;
|
||||
|
||||
/**
|
||||
* Payload type, TRANSFORM_ATTRIBUTE or TRANSFORM_ATTRIBUTE_V1
|
||||
*/
|
||||
payload_type_t type;
|
||||
};
|
||||
|
||||
|
||||
ENUM_BEGIN(transform_attribute_type_name, ATTRIBUTE_UNDEFINED, ATTRIBUTE_UNDEFINED,
|
||||
"ATTRIBUTE_UNDEFINED");
|
||||
ENUM_NEXT(transform_attribute_type_name, KEY_LENGTH, KEY_LENGTH, ATTRIBUTE_UNDEFINED,
|
||||
"KEY_LENGTH");
|
||||
ENUM_END(transform_attribute_type_name, KEY_LENGTH);
|
||||
|
||||
/**
|
||||
* 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 rules for IKEv1/IKEv2 transform attributes
|
||||
*/
|
||||
encoding_rule_t transform_attribute_encodings[] = {
|
||||
static encoding_rule_t 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 */
|
||||
|
@ -101,18 +134,23 @@ METHOD(payload_t, verify, status_t,
|
|||
return SUCCESS;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_encoding_rules, void,
|
||||
private_transform_attribute_t *this, encoding_rule_t **rules,
|
||||
size_t *rule_count)
|
||||
METHOD(payload_t, get_encoding_rules, int,
|
||||
private_transform_attribute_t *this, encoding_rule_t **rules)
|
||||
{
|
||||
*rules = transform_attribute_encodings;
|
||||
*rule_count = countof(transform_attribute_encodings);
|
||||
*rules = encodings;
|
||||
return countof(encodings);
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_header_length, int,
|
||||
private_transform_attribute_t *this)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_type, payload_type_t,
|
||||
private_transform_attribute_t *this)
|
||||
{
|
||||
return TRANSFORM_ATTRIBUTE;
|
||||
return this->type;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_next_type, payload_type_t,
|
||||
|
@ -136,31 +174,6 @@ METHOD(payload_t, get_length, size_t,
|
|||
return this->attribute_length_or_value + 4;
|
||||
}
|
||||
|
||||
METHOD(transform_attribute_t, set_value_chunk, void,
|
||||
private_transform_attribute_t *this, chunk_t value)
|
||||
{
|
||||
chunk_free(&this->attribute_value);
|
||||
|
||||
if (value.len != 2)
|
||||
{
|
||||
this->attribute_value = chunk_clone(value);
|
||||
this->attribute_length_or_value = value.len;
|
||||
this->attribute_format = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(&this->attribute_length_or_value, value.ptr, value.len);
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(transform_attribute_t, set_value, void,
|
||||
private_transform_attribute_t *this, u_int16_t value)
|
||||
{
|
||||
chunk_free(&this->attribute_value);
|
||||
this->attribute_length_or_value = value;
|
||||
this->attribute_format = TRUE;
|
||||
}
|
||||
|
||||
METHOD(transform_attribute_t, get_value_chunk, chunk_t,
|
||||
private_transform_attribute_t *this)
|
||||
{
|
||||
|
@ -171,16 +184,22 @@ METHOD(transform_attribute_t, get_value_chunk, chunk_t,
|
|||
return this->attribute_value;
|
||||
}
|
||||
|
||||
METHOD(transform_attribute_t, get_value, u_int16_t,
|
||||
METHOD(transform_attribute_t, get_value, u_int64_t,
|
||||
private_transform_attribute_t *this)
|
||||
{
|
||||
return this->attribute_length_or_value;
|
||||
}
|
||||
u_int64_t value = 0;
|
||||
|
||||
METHOD(transform_attribute_t, set_attribute_type, void,
|
||||
private_transform_attribute_t *this, u_int16_t type)
|
||||
{
|
||||
this->attribute_type = type & 0x7FFF;
|
||||
if (this->attribute_format)
|
||||
{
|
||||
return this->attribute_length_or_value;
|
||||
}
|
||||
if (this->attribute_value.len > sizeof(value))
|
||||
{
|
||||
return UINT64_MAX;
|
||||
}
|
||||
memcpy(((char*)&value) + sizeof(value) - this->attribute_value.len,
|
||||
this->attribute_value.ptr, this->attribute_value.len);
|
||||
return untoh64((char*)&value);
|
||||
}
|
||||
|
||||
METHOD(transform_attribute_t, get_attribute_type, u_int16_t,
|
||||
|
@ -189,24 +208,6 @@ METHOD(transform_attribute_t, get_attribute_type, u_int16_t,
|
|||
return this->attribute_type;
|
||||
}
|
||||
|
||||
METHOD(transform_attribute_t, clone_, transform_attribute_t*,
|
||||
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 = chunk_clone(this->attribute_value);
|
||||
}
|
||||
return &new_clone->public;
|
||||
}
|
||||
|
||||
METHOD2(payload_t, transform_attribute_t, destroy, void,
|
||||
private_transform_attribute_t *this)
|
||||
{
|
||||
|
@ -217,7 +218,7 @@ METHOD2(payload_t, transform_attribute_t, destroy, void,
|
|||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
transform_attribute_t *transform_attribute_create()
|
||||
transform_attribute_t *transform_attribute_create(payload_type_t type)
|
||||
{
|
||||
private_transform_attribute_t *this;
|
||||
|
||||
|
@ -226,22 +227,20 @@ transform_attribute_t *transform_attribute_create()
|
|||
.payload_interface = {
|
||||
.verify = _verify,
|
||||
.get_encoding_rules = _get_encoding_rules,
|
||||
.get_header_length = _get_header_length,
|
||||
.get_length = _get_length,
|
||||
.get_next_type = _get_next_type,
|
||||
.set_next_type = _set_next_type,
|
||||
.get_type = _get_type,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.set_value_chunk = _set_value_chunk,
|
||||
.set_value = _set_value,
|
||||
.get_value_chunk = _get_value_chunk,
|
||||
.get_value = _get_value,
|
||||
.set_attribute_type = _set_attribute_type,
|
||||
.get_attribute_type = _get_attribute_type,
|
||||
.clone = _clone_,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.attribute_format = TRUE,
|
||||
.attribute_format = FALSE,
|
||||
.type = type,
|
||||
);
|
||||
return &this->public;
|
||||
}
|
||||
|
@ -249,10 +248,33 @@ transform_attribute_t *transform_attribute_create()
|
|||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
transform_attribute_t *transform_attribute_create_key_length(u_int16_t key_length)
|
||||
transform_attribute_t *transform_attribute_create_value(payload_type_t type,
|
||||
transform_attribute_type_t kind, u_int64_t value)
|
||||
{
|
||||
transform_attribute_t *attribute = transform_attribute_create();
|
||||
attribute->set_attribute_type(attribute, KEY_LENGTH);
|
||||
attribute->set_value(attribute, key_length);
|
||||
return attribute;
|
||||
private_transform_attribute_t *this;
|
||||
|
||||
this = (private_transform_attribute_t*)transform_attribute_create(type);
|
||||
|
||||
this->attribute_type = kind & 0x7FFF;
|
||||
|
||||
if (value <= UINT16_MAX)
|
||||
{
|
||||
this->attribute_length_or_value = value;
|
||||
this->attribute_format = TRUE;
|
||||
}
|
||||
else if (value <= UINT32_MAX)
|
||||
{
|
||||
u_int32_t val32;
|
||||
|
||||
val32 = htonl(value);
|
||||
this->attribute_value = chunk_clone(chunk_from_thing(val32));
|
||||
this->attribute_length_or_value = sizeof(val32);
|
||||
}
|
||||
else
|
||||
{
|
||||
htoun64(&value, value);
|
||||
this->attribute_value = chunk_clone(chunk_from_thing(value));
|
||||
this->attribute_length_or_value = sizeof(value);
|
||||
}
|
||||
return &this->public;
|
||||
}
|
||||
|
|
|
@ -28,26 +28,66 @@ typedef struct transform_attribute_t transform_attribute_t;
|
|||
#include <library.h>
|
||||
#include <encoding/payloads/payload.h>
|
||||
|
||||
|
||||
/**
|
||||
* Type of the attribute, as in IKEv2 RFC 3.3.5.
|
||||
* Type of the attribute.
|
||||
*/
|
||||
enum transform_attribute_type_t {
|
||||
ATTRIBUTE_UNDEFINED = 16384,
|
||||
KEY_LENGTH = 14
|
||||
/** IKEv1 Phase 1 attributes */
|
||||
TATTR_PH1_ENCRYPTION_ALGORITHM = 1,
|
||||
TATTR_PH1_HASH_ALGORITHM = 2,
|
||||
TATTR_PH1_AUTH_METHOD = 3,
|
||||
TATTR_PH1_GROUP = 4,
|
||||
TATTR_PH1_GROUP_TYPE = 5,
|
||||
TATTR_PH1_GROUP_PRIME = 6,
|
||||
TATTR_PH1_GROUP_GENONE = 7,
|
||||
TATTR_PH1_GROUP_GENTWO = 8,
|
||||
TATTR_PH1_GROUP_CURVE_A = 9,
|
||||
TATTR_PH1_GROUP_CURVE_B = 10,
|
||||
TATTR_PH1_LIFE_TYPE = 11,
|
||||
TATTR_PH1_LIFE_DURATION = 12,
|
||||
TATTR_PH1_PRF = 13,
|
||||
TATTR_PH1_KEY_LENGTH = 14,
|
||||
TATTR_PH1_FIELD_SIZE = 15,
|
||||
TATTR_PH1_GROUP_ORDER = 16,
|
||||
/** IKEv1 Phase 2 attributes */
|
||||
TATTR_PH2_SA_LIFE_TYPE = 1,
|
||||
TATTR_PH2_SA_LIFE_DURATION = 2,
|
||||
TATTR_PH2_GROUP = 3,
|
||||
TATTR_PH2_ENCAP_MODE = 4,
|
||||
TATTR_PH2_AUTH_ALGORITHM = 5,
|
||||
TATTR_PH2_KEY_LENGTH = 6,
|
||||
TATTR_PH2_KEY_ROUNDS = 7,
|
||||
TATTR_PH2_COMP_DICT_SIZE = 8,
|
||||
TATTR_PH2_COMP_PRIV_ALGORITHM = 9,
|
||||
TATTR_PH2_ECN_TUNNEL = 10,
|
||||
TATTR_PH2_EXT_SEQ_NUMBER = 11,
|
||||
/* IKEv2 key length attribute */
|
||||
TATTR_IKEV2_KEY_LENGTH = 14,
|
||||
/* undefined, private use attribute */
|
||||
TATTR_UNDEFINED = 16384,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum name for transform_attribute_type_t.
|
||||
* Enum names for IKEv1 Phase 1 transform_attribute_type_t.
|
||||
*/
|
||||
extern enum_name_t *transform_attribute_type_names;
|
||||
extern enum_name_t *tattr_ph1_names;
|
||||
|
||||
/**
|
||||
* Class representing an IKEv2- TRANSFORM Attribute.
|
||||
*
|
||||
* The TRANSFORM ATTRIBUTE format is described in RFC section 3.3.5.
|
||||
* Enum names for IKEv1 Phase 2 transform_attribute_type_t.
|
||||
*/
|
||||
extern enum_name_t *tattr_ph2_names;
|
||||
|
||||
/**
|
||||
* Enum names for IKEv2 transform_attribute_type_t.
|
||||
*/
|
||||
extern enum_name_t *tattr_ikev2_names;
|
||||
|
||||
|
||||
/**
|
||||
* Class representing an IKEv1/IKEv2 TRANSFORM Attribute.
|
||||
*/
|
||||
struct transform_attribute_t {
|
||||
|
||||
/**
|
||||
* The payload_t interface.
|
||||
*/
|
||||
|
@ -58,7 +98,7 @@ struct transform_attribute_t {
|
|||
*
|
||||
* Returned data are not copied.
|
||||
*
|
||||
* @return chunk_t pointing to the value
|
||||
* @return chunk_t pointing to internal value
|
||||
*/
|
||||
chunk_t (*get_value_chunk) (transform_attribute_t *this);
|
||||
|
||||
|
@ -69,30 +109,7 @@ struct transform_attribute_t {
|
|||
*
|
||||
* @return value
|
||||
*/
|
||||
u_int16_t (*get_value) (transform_attribute_t *this);
|
||||
|
||||
/**
|
||||
* Sets the value of the attribute.
|
||||
*
|
||||
* Value is getting copied.
|
||||
*
|
||||
* @param value chunk_t pointing to the value to set
|
||||
*/
|
||||
void (*set_value_chunk) (transform_attribute_t *this, chunk_t value);
|
||||
|
||||
/**
|
||||
* Sets the value of the attribute.
|
||||
*
|
||||
* @param value value to set
|
||||
*/
|
||||
void (*set_value) (transform_attribute_t *this, u_int16_t value);
|
||||
|
||||
/**
|
||||
* Sets the type of the attribute.
|
||||
*
|
||||
* @param type type to set (most significant bit is set to zero)
|
||||
*/
|
||||
void (*set_attribute_type) (transform_attribute_t *this, u_int16_t type);
|
||||
u_int64_t (*get_value) (transform_attribute_t *this);
|
||||
|
||||
/**
|
||||
* get the type of the attribute.
|
||||
|
@ -101,13 +118,6 @@ struct transform_attribute_t {
|
|||
*/
|
||||
u_int16_t (*get_attribute_type) (transform_attribute_t *this);
|
||||
|
||||
/**
|
||||
* Clones an transform_attribute_t object.
|
||||
*
|
||||
* @return cloned transform_attribute_t object
|
||||
*/
|
||||
transform_attribute_t * (*clone) (transform_attribute_t *this);
|
||||
|
||||
/**
|
||||
* Destroys an transform_attribute_t object.
|
||||
*/
|
||||
|
@ -117,16 +127,20 @@ struct transform_attribute_t {
|
|||
/**
|
||||
* Creates an empty transform_attribute_t object.
|
||||
*
|
||||
* @param type TRANSFORM_ATTRIBUTE or TRANSFORM_ATTRIBUTE_V1
|
||||
* @return transform_attribute_t object
|
||||
*/
|
||||
transform_attribute_t *transform_attribute_create(void);
|
||||
transform_attribute_t *transform_attribute_create(payload_type_t type);
|
||||
|
||||
/**
|
||||
* Creates an transform_attribute_t of type KEY_LENGTH.
|
||||
* Creates a two byte value or a larger attribute for a given attribute kind.
|
||||
*
|
||||
* @param key_length key length in bytes
|
||||
* @param type TRANSFORM_ATTRIBUTE or TRANSFORM_ATTRIBUTE_V1
|
||||
* @param kind attribute kind
|
||||
* @param value fixed two byte value
|
||||
* @return transform_attribute_t object
|
||||
*/
|
||||
transform_attribute_t *transform_attribute_create_key_length(u_int16_t key_length);
|
||||
transform_attribute_t *transform_attribute_create_value(payload_type_t type,
|
||||
transform_attribute_type_t kind, u_int64_t value);
|
||||
|
||||
#endif /** TRANSFORM_ATTRIBUTE_H_ @}*/
|
||||
|
|
|
@ -41,10 +41,11 @@ struct private_transform_substructure_t {
|
|||
* Next payload type.
|
||||
*/
|
||||
u_int8_t next_payload;
|
||||
|
||||
/**
|
||||
* Reserved bytes
|
||||
* Reserved byte
|
||||
*/
|
||||
u_int8_t reserved[2];
|
||||
u_int8_t reserved[3];
|
||||
|
||||
/**
|
||||
* Length of this payload.
|
||||
|
@ -52,43 +53,72 @@ struct private_transform_substructure_t {
|
|||
u_int16_t transform_length;
|
||||
|
||||
/**
|
||||
* Type of the transform.
|
||||
* Type or number, Type of the transform in IKEv2, number in IKEv2.
|
||||
*/
|
||||
u_int8_t transform_type;
|
||||
u_int8_t transform_ton;
|
||||
|
||||
/**
|
||||
* Transform ID.
|
||||
* Transform ID, as encoded in IKEv1.
|
||||
*/
|
||||
u_int16_t transform_id;
|
||||
u_int8_t transform_id_v1;
|
||||
|
||||
/**
|
||||
* Transform ID, as encoded in IKEv2.
|
||||
*/
|
||||
u_int16_t transform_id_v2;
|
||||
|
||||
/**
|
||||
* Transforms Attributes are stored in a linked_list_t.
|
||||
*/
|
||||
linked_list_t *attributes;
|
||||
|
||||
/**
|
||||
* Payload type, TRANSFORM_SUBSTRUCTURE or TRANSFORM_SUBSTRUCTURE_V1
|
||||
*/
|
||||
payload_type_t type;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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 rules for TRANSFORM_SUBSTRUCTURE
|
||||
*/
|
||||
encoding_rule_t transform_substructure_encodings[] = {
|
||||
static encoding_rule_t encodings_v2[] = {
|
||||
/* 1 Byte next payload type, stored in the field next_payload */
|
||||
{ U_INT_8, offsetof(private_transform_substructure_t, next_payload) },
|
||||
{ U_INT_8, offsetof(private_transform_substructure_t, next_payload) },
|
||||
/* 1 Reserved Byte */
|
||||
{ RESERVED_BYTE, offsetof(private_transform_substructure_t, reserved[0]) },
|
||||
{ RESERVED_BYTE, offsetof(private_transform_substructure_t, reserved[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) },
|
||||
{ PAYLOAD_LENGTH, offsetof(private_transform_substructure_t, transform_length)},
|
||||
/* transform type */
|
||||
{ U_INT_8, offsetof(private_transform_substructure_t, transform_ton) },
|
||||
/* transform identifier, as used by IKEv1 */
|
||||
{ RESERVED_BYTE, offsetof(private_transform_substructure_t, reserved[1]) },
|
||||
/* transform identifier, as used by IKEv2 */
|
||||
{ U_INT_16, offsetof(private_transform_substructure_t, transform_id_v2) },
|
||||
/* Attributes in a transform attribute list */
|
||||
{ PAYLOAD_LIST + TRANSFORM_ATTRIBUTE,
|
||||
offsetof(private_transform_substructure_t, attributes) }
|
||||
};
|
||||
|
||||
/**
|
||||
* Encoding rules for TRANSFORM_SUBSTRUCTURE_V1
|
||||
*/
|
||||
static encoding_rule_t encodings_v1[] = {
|
||||
/* 1 Byte next payload type, stored in the field next_payload */
|
||||
{ U_INT_8, offsetof(private_transform_substructure_t, next_payload) },
|
||||
/* 1 Reserved Byte */
|
||||
{ RESERVED_BYTE, offsetof(private_transform_substructure_t, reserved[1]) },
|
||||
/* transform 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) }
|
||||
{ RESERVED_BYTE, offsetof(private_transform_substructure_t, reserved[0]) },
|
||||
/* Length of the whole transform substructure*/
|
||||
{ PAYLOAD_LENGTH, offsetof(private_transform_substructure_t, transform_length)},
|
||||
/* transform number */
|
||||
{ U_INT_8, offsetof(private_transform_substructure_t, transform_ton)},
|
||||
/* transform identifier, as used by IKEv1 */
|
||||
{ U_INT_8, offsetof(private_transform_substructure_t, transform_id_v1) },
|
||||
/* transform identifier, as used by IKEv2 */
|
||||
{ RESERVED_BYTE, offsetof(private_transform_substructure_t, reserved[1]) },
|
||||
{ RESERVED_BYTE, offsetof(private_transform_substructure_t, reserved[2]) },
|
||||
/* Attributes in a transform attribute list */
|
||||
{ PAYLOAD_LIST + TRANSFORM_ATTRIBUTE_V1,
|
||||
offsetof(private_transform_substructure_t, attributes) }
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -97,7 +127,7 @@ encoding_rule_t transform_substructure_encodings[] = {
|
|||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! 0 (last) or 3 ! RESERVED ! Transform Length !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
!Transform Type ! RESERVED ! Transform ID !
|
||||
! Tfrm Typ or # ! Tfrm ID IKEv1 ! Transform ID IKEv2 !
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
! !
|
||||
~ Transform Attributes ~
|
||||
|
@ -118,23 +148,6 @@ METHOD(payload_t, verify, status_t,
|
|||
return FAILED;
|
||||
}
|
||||
|
||||
switch (this->transform_type)
|
||||
{
|
||||
case ENCRYPTION_ALGORITHM:
|
||||
case PSEUDO_RANDOM_FUNCTION:
|
||||
case INTEGRITY_ALGORITHM:
|
||||
case DIFFIE_HELLMAN_GROUP:
|
||||
case EXTENDED_SEQUENCE_NUMBERS:
|
||||
/* we don't check transform ID, we want to reply
|
||||
* cleanly with NO_PROPOSAL_CHOSEN or so if we don't support it */
|
||||
break;
|
||||
default:
|
||||
{
|
||||
DBG1(DBG_ENC, "invalid transform type: %d", this->transform_type);
|
||||
return FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
enumerator = this->attributes->create_enumerator(this->attributes);
|
||||
while (enumerator->enumerate(enumerator, &attribute))
|
||||
{
|
||||
|
@ -151,18 +164,28 @@ METHOD(payload_t, verify, status_t,
|
|||
return status;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_encoding_rules, void,
|
||||
private_transform_substructure_t *this, encoding_rule_t **rules,
|
||||
size_t *rule_count)
|
||||
METHOD(payload_t, get_encoding_rules, int,
|
||||
private_transform_substructure_t *this, encoding_rule_t **rules)
|
||||
{
|
||||
*rules = transform_substructure_encodings;
|
||||
*rule_count = countof(transform_substructure_encodings);
|
||||
if (this->type == TRANSFORM_SUBSTRUCTURE)
|
||||
{
|
||||
*rules = encodings_v2;
|
||||
return countof(encodings_v2);
|
||||
}
|
||||
*rules = encodings_v1;
|
||||
return countof(encodings_v1);
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_header_length, int,
|
||||
private_transform_substructure_t *this)
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_type, payload_type_t,
|
||||
private_transform_substructure_t *this)
|
||||
{
|
||||
return TRANSFORM_SUBSTRUCTURE;
|
||||
return this->type;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_next_type, payload_type_t,
|
||||
|
@ -174,12 +197,12 @@ METHOD(payload_t, get_next_type, payload_type_t,
|
|||
/**
|
||||
* recompute the length of the payload.
|
||||
*/
|
||||
static void compute_length (private_transform_substructure_t *this)
|
||||
static void compute_length(private_transform_substructure_t *this)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
payload_t *attribute;
|
||||
|
||||
this->transform_length = TRANSFORM_SUBSTRUCTURE_HEADER_LENGTH;
|
||||
this->transform_length = get_header_length(this);
|
||||
enumerator = this->attributes->create_enumerator(this->attributes);
|
||||
while (enumerator->enumerate(enumerator, &attribute))
|
||||
{
|
||||
|
@ -194,6 +217,13 @@ METHOD(payload_t, get_length, size_t,
|
|||
return this->transform_length;
|
||||
}
|
||||
|
||||
METHOD(transform_substructure_t, add_transform_attribute, void,
|
||||
private_transform_substructure_t *this, transform_attribute_t *attribute)
|
||||
{
|
||||
this->attributes->insert_last(this->attributes, attribute);
|
||||
compute_length(this);
|
||||
}
|
||||
|
||||
METHOD(transform_substructure_t, set_is_last_transform, void,
|
||||
private_transform_substructure_t *this, bool is_last)
|
||||
{
|
||||
|
@ -205,50 +235,40 @@ METHOD(payload_t, set_next_type, void,
|
|||
{
|
||||
}
|
||||
|
||||
METHOD(transform_substructure_t, get_transform_type, u_int8_t,
|
||||
METHOD(transform_substructure_t, get_transform_type_or_number, u_int8_t,
|
||||
private_transform_substructure_t *this)
|
||||
{
|
||||
return this->transform_type;
|
||||
return this->transform_ton;
|
||||
}
|
||||
|
||||
METHOD(transform_substructure_t, get_transform_id, u_int16_t,
|
||||
private_transform_substructure_t *this)
|
||||
{
|
||||
return this->transform_id;
|
||||
if (this->type == TRANSFORM_SUBSTRUCTURE)
|
||||
{
|
||||
return this->transform_id_v2;
|
||||
}
|
||||
return this->transform_id_v1;
|
||||
}
|
||||
|
||||
METHOD(transform_substructure_t, get_key_length, status_t,
|
||||
private_transform_substructure_t *this, u_int16_t *key_length)
|
||||
METHOD(transform_substructure_t, create_attribute_enumerator, enumerator_t*,
|
||||
private_transform_substructure_t *this)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
transform_attribute_t *attribute;
|
||||
|
||||
enumerator = this->attributes->create_enumerator(this->attributes);
|
||||
while (enumerator->enumerate(enumerator, &attribute))
|
||||
{
|
||||
if (attribute->get_attribute_type(attribute) == KEY_LENGTH)
|
||||
{
|
||||
*key_length = attribute->get_value(attribute);
|
||||
enumerator->destroy(enumerator);
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
return FAILED;
|
||||
return this->attributes->create_enumerator(this->attributes);
|
||||
}
|
||||
|
||||
METHOD2(payload_t, transform_substructure_t, destroy, void,
|
||||
private_transform_substructure_t *this)
|
||||
{
|
||||
this->attributes->destroy_offset(this->attributes,
|
||||
offsetof(transform_attribute_t, destroy));
|
||||
offsetof(payload_t, destroy));
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
transform_substructure_t *transform_substructure_create()
|
||||
transform_substructure_t *transform_substructure_create(payload_type_t type)
|
||||
{
|
||||
private_transform_substructure_t *this;
|
||||
|
||||
|
@ -257,21 +277,24 @@ transform_substructure_t *transform_substructure_create()
|
|||
.payload_interface = {
|
||||
.verify = _verify,
|
||||
.get_encoding_rules = _get_encoding_rules,
|
||||
.get_header_length = _get_header_length,
|
||||
.get_length = _get_length,
|
||||
.get_next_type = _get_next_type,
|
||||
.set_next_type = _set_next_type,
|
||||
.get_type = _get_type,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.add_transform_attribute = _add_transform_attribute,
|
||||
.set_is_last_transform = _set_is_last_transform,
|
||||
.get_transform_type = _get_transform_type,
|
||||
.get_transform_type_or_number = _get_transform_type_or_number,
|
||||
.get_transform_id = _get_transform_id,
|
||||
.get_key_length = _get_key_length,
|
||||
.create_attribute_enumerator = _create_attribute_enumerator,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.next_payload = NO_PAYLOAD,
|
||||
.transform_length = TRANSFORM_SUBSTRUCTURE_HEADER_LENGTH,
|
||||
.transform_length = get_header_length(this),
|
||||
.attributes = linked_list_create(),
|
||||
.type = type,
|
||||
);
|
||||
return &this->public;
|
||||
}
|
||||
|
@ -279,20 +302,21 @@ transform_substructure_t *transform_substructure_create()
|
|||
/*
|
||||
* Described in header
|
||||
*/
|
||||
transform_substructure_t *transform_substructure_create_type(
|
||||
transform_type_t type, u_int16_t id, u_int16_t key_length)
|
||||
transform_substructure_t *transform_substructure_create_type(payload_type_t type,
|
||||
u_int8_t type_or_number, u_int16_t id)
|
||||
{
|
||||
private_transform_substructure_t *this;
|
||||
|
||||
this = (private_transform_substructure_t*)transform_substructure_create();
|
||||
this = (private_transform_substructure_t*)transform_substructure_create(type);
|
||||
|
||||
this->transform_type = type;
|
||||
this->transform_id = id;
|
||||
if (key_length)
|
||||
this->transform_ton = type_or_number;
|
||||
if (type == TRANSFORM_SUBSTRUCTURE)
|
||||
{
|
||||
this->attributes->insert_last(this->attributes,
|
||||
(void*)transform_attribute_create_key_length(key_length));
|
||||
compute_length(this);
|
||||
this->transform_id_v2 = id;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->transform_id_v1 = id;
|
||||
}
|
||||
return &this->public;
|
||||
}
|
||||
|
|
|
@ -40,14 +40,7 @@ typedef struct transform_substructure_t transform_substructure_t;
|
|||
#define TRANSFORM_TYPE_VALUE 3
|
||||
|
||||
/**
|
||||
* Length of the transform substructure header in bytes.
|
||||
*/
|
||||
#define TRANSFORM_SUBSTRUCTURE_HEADER_LENGTH 8
|
||||
|
||||
/**
|
||||
* Class representing an IKEv2- TRANSFORM SUBSTRUCTURE.
|
||||
*
|
||||
* The TRANSFORM SUBSTRUCTURE format is described in RFC section 3.3.2.
|
||||
* Class representing an IKEv1/IKEv2 transform substructure.
|
||||
*/
|
||||
struct transform_substructure_t {
|
||||
|
||||
|
@ -75,11 +68,11 @@ struct transform_substructure_t {
|
|||
void (*set_is_last_transform) (transform_substructure_t *this, bool is_last);
|
||||
|
||||
/**
|
||||
* get transform type of the current transform.
|
||||
* Get transform type (IKEv2) or the transform number (IKEv1).
|
||||
*
|
||||
* @return Transform type of current transform substructure.
|
||||
*/
|
||||
u_int8_t (*get_transform_type) (transform_substructure_t *this);
|
||||
u_int8_t (*get_transform_type_or_number) (transform_substructure_t *this);
|
||||
|
||||
/**
|
||||
* Get transform id of the current transform.
|
||||
|
@ -89,16 +82,11 @@ struct transform_substructure_t {
|
|||
u_int16_t (*get_transform_id) (transform_substructure_t *this);
|
||||
|
||||
/**
|
||||
* Get transform id of the current transform.
|
||||
* Create an enumerator over transform attributes.
|
||||
*
|
||||
* @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!
|
||||
* @return enumerator over transform_attribute_t*
|
||||
*/
|
||||
status_t (*get_key_length) (transform_substructure_t *this,
|
||||
u_int16_t *key_length);
|
||||
enumerator_t* (*create_attribute_enumerator)(transform_substructure_t *this);
|
||||
|
||||
/**
|
||||
* Destroys an transform_substructure_t object.
|
||||
|
@ -109,19 +97,20 @@ struct transform_substructure_t {
|
|||
/**
|
||||
* Creates an empty transform_substructure_t object.
|
||||
*
|
||||
* @param type TRANSFORM_SUBSTRUCTURE or TRANSFORM_SUBSTRUCTURE_V1
|
||||
* @return created transform_substructure_t object
|
||||
*/
|
||||
transform_substructure_t *transform_substructure_create(void);
|
||||
transform_substructure_t *transform_substructure_create(payload_type_t type);
|
||||
|
||||
/**
|
||||
* Creates an empty transform_substructure_t object.
|
||||
*
|
||||
* @param type type of transform to create
|
||||
* @param id transform id specifc for the transform type
|
||||
* @param key_length key length for key length attribute, 0 to omit
|
||||
* @return transform_substructure_t object
|
||||
* @param type TRANSFORM_SUBSTRUCTURE or TRANSFORM_SUBSTRUCTURE_V1
|
||||
* @param type_or_number Type (IKEv2) or number (IKEv1) of transform
|
||||
* @param id transform id specifc for the transform type
|
||||
* @return transform_substructure_t object
|
||||
*/
|
||||
transform_substructure_t *transform_substructure_create_type(
|
||||
transform_type_t type, u_int16_t id, u_int16_t key_length);
|
||||
transform_substructure_t *transform_substructure_create_type(payload_type_t type,
|
||||
u_int8_t type_or_number, u_int16_t id);
|
||||
|
||||
#endif /** TRANSFORM_SUBSTRUCTURE_H_ @}*/
|
||||
|
|
|
@ -81,7 +81,7 @@ struct private_ts_payload_t {
|
|||
* The defined offsets are the positions in a object of type
|
||||
* private_ts_payload_t.
|
||||
*/
|
||||
encoding_rule_t ts_payload_encodings[] = {
|
||||
static encoding_rule_t 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 */
|
||||
|
@ -102,8 +102,9 @@ encoding_rule_t ts_payload_encodings[] = {
|
|||
{ RESERVED_BYTE, offsetof(private_ts_payload_t, reserved_byte[0])},
|
||||
{ RESERVED_BYTE, offsetof(private_ts_payload_t, reserved_byte[1])},
|
||||
{ RESERVED_BYTE, offsetof(private_ts_payload_t, reserved_byte[2])},
|
||||
/* some ts data bytes, length is defined in PAYLOAD_LENGTH */
|
||||
{ TRAFFIC_SELECTORS,offsetof(private_ts_payload_t, substrs) }
|
||||
/* wrapped list of traffic selectors substructures */
|
||||
{ PAYLOAD_LIST + TRAFFIC_SELECTOR_SUBSTRUCTURE,
|
||||
offsetof(private_ts_payload_t, substrs) },
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -145,11 +146,17 @@ METHOD(payload_t, verify, status_t,
|
|||
return status;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_encoding_rules, void,
|
||||
private_ts_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
|
||||
METHOD(payload_t, get_encoding_rules, int,
|
||||
private_ts_payload_t *this, encoding_rule_t **rules)
|
||||
{
|
||||
*rules = ts_payload_encodings;
|
||||
*rule_count = countof(ts_payload_encodings);
|
||||
*rules = encodings;
|
||||
return countof(encodings);
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_header_length, int,
|
||||
private_ts_payload_t *this)
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_type, payload_type_t,
|
||||
|
@ -182,7 +189,7 @@ static void compute_length(private_ts_payload_t *this)
|
|||
enumerator_t *enumerator;
|
||||
payload_t *subst;
|
||||
|
||||
this->payload_length = TS_PAYLOAD_HEADER_LENGTH;
|
||||
this->payload_length = get_header_length(this);
|
||||
this->ts_num = 0;
|
||||
enumerator = this->substrs->create_enumerator(this->substrs);
|
||||
while (enumerator->enumerate(enumerator, &subst))
|
||||
|
@ -250,6 +257,7 @@ ts_payload_t *ts_payload_create(bool is_initiator)
|
|||
.payload_interface = {
|
||||
.verify = _verify,
|
||||
.get_encoding_rules = _get_encoding_rules,
|
||||
.get_header_length = _get_header_length,
|
||||
.get_length = _get_length,
|
||||
.get_next_type = _get_next_type,
|
||||
.set_next_type = _set_next_type,
|
||||
|
@ -262,7 +270,7 @@ ts_payload_t *ts_payload_create(bool is_initiator)
|
|||
.destroy = _destroy,
|
||||
},
|
||||
.next_payload = NO_PAYLOAD,
|
||||
.payload_length = TS_PAYLOAD_HEADER_LENGTH,
|
||||
.payload_length = get_header_length(this),
|
||||
.is_initiator = is_initiator,
|
||||
.substrs = linked_list_create(),
|
||||
);
|
||||
|
|
|
@ -30,11 +30,6 @@ typedef struct ts_payload_t ts_payload_t;
|
|||
#include <encoding/payloads/payload.h>
|
||||
#include <encoding/payloads/traffic_selector_substructure.h>
|
||||
|
||||
/**
|
||||
* Length of a TS payload without the Traffic selectors.
|
||||
*/
|
||||
#define TS_PAYLOAD_HEADER_LENGTH 8
|
||||
|
||||
/**
|
||||
* Class representing an IKEv2 TS payload.
|
||||
*
|
||||
|
|
|
@ -68,7 +68,7 @@ struct private_unknown_payload_t {
|
|||
* private_unknown_payload_t.
|
||||
*
|
||||
*/
|
||||
encoding_rule_t unknown_payload_encodings[] = {
|
||||
static encoding_rule_t 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 */
|
||||
|
@ -84,7 +84,7 @@ encoding_rule_t unknown_payload_encodings[] = {
|
|||
/* 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) },
|
||||
{ CHUNK_DATA, offsetof(private_unknown_payload_t, data) },
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -102,18 +102,20 @@ encoding_rule_t unknown_payload_encodings[] = {
|
|||
METHOD(payload_t, verify, status_t,
|
||||
private_unknown_payload_t *this)
|
||||
{
|
||||
if (this->payload_length != UNKNOWN_PAYLOAD_HEADER_LENGTH + this->data.len)
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_encoding_rules, void,
|
||||
private_unknown_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
|
||||
METHOD(payload_t, get_encoding_rules, int,
|
||||
private_unknown_payload_t *this, encoding_rule_t **rules)
|
||||
{
|
||||
*rules = unknown_payload_encodings;
|
||||
*rule_count = sizeof(unknown_payload_encodings) / sizeof(encoding_rule_t);
|
||||
*rules = encodings;
|
||||
return countof(encodings);
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_header_length, int,
|
||||
private_unknown_payload_t *this)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_payload_type, payload_type_t,
|
||||
|
@ -171,6 +173,7 @@ unknown_payload_t *unknown_payload_create(payload_type_t type)
|
|||
.payload_interface = {
|
||||
.verify = _verify,
|
||||
.get_encoding_rules = _get_encoding_rules,
|
||||
.get_header_length = _get_header_length,
|
||||
.get_length = _get_length,
|
||||
.get_next_type = _get_next_type,
|
||||
.set_next_type = _set_next_type,
|
||||
|
@ -182,7 +185,7 @@ unknown_payload_t *unknown_payload_create(payload_type_t type)
|
|||
.destroy = _destroy,
|
||||
},
|
||||
.next_payload = NO_PAYLOAD,
|
||||
.payload_length = UNKNOWN_PAYLOAD_HEADER_LENGTH,
|
||||
.payload_length = get_header_length(this),
|
||||
.type = type,
|
||||
);
|
||||
|
||||
|
@ -201,7 +204,7 @@ unknown_payload_t *unknown_payload_create_data(payload_type_t type,
|
|||
this = (private_unknown_payload_t*)unknown_payload_create(type);
|
||||
this->data = data;
|
||||
this->critical = critical;
|
||||
this->payload_length = UNKNOWN_PAYLOAD_HEADER_LENGTH + data.len;
|
||||
this->payload_length = get_header_length(this) + data.len;
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
|
|
@ -27,11 +27,6 @@ typedef struct unknown_payload_t unknown_payload_t;
|
|||
#include <library.h>
|
||||
#include <encoding/payloads/payload.h>
|
||||
|
||||
/**
|
||||
* Header length of the unknown payload.
|
||||
*/
|
||||
#define UNKNOWN_PAYLOAD_HEADER_LENGTH 4
|
||||
|
||||
/**
|
||||
* Payload which can't be processed further.
|
||||
*
|
||||
|
|
|
@ -55,6 +55,11 @@ struct private_vendor_id_payload_t {
|
|||
* The contained data.
|
||||
*/
|
||||
chunk_t data;
|
||||
|
||||
/**
|
||||
* Either a IKEv1 or a IKEv2 vendor ID payload
|
||||
*/
|
||||
payload_type_t type;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -63,7 +68,7 @@ struct private_vendor_id_payload_t {
|
|||
* The defined offsets are the positions in a object of type
|
||||
* private_vendor_id_payload_t.
|
||||
*/
|
||||
encoding_rule_t vendor_id_payload_encodings[] = {
|
||||
static encoding_rule_t 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 */
|
||||
|
@ -79,7 +84,7 @@ encoding_rule_t vendor_id_payload_encodings[] = {
|
|||
/* 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, data) }
|
||||
{ CHUNK_DATA, offsetof(private_vendor_id_payload_t, data) }
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -100,18 +105,23 @@ METHOD(payload_t, verify, status_t,
|
|||
return SUCCESS;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_encoding_rules, void,
|
||||
private_vendor_id_payload_t *this, encoding_rule_t **rules,
|
||||
size_t *rule_count)
|
||||
METHOD(payload_t, get_encoding_rules, int,
|
||||
private_vendor_id_payload_t *this, encoding_rule_t **rules)
|
||||
{
|
||||
*rules = vendor_id_payload_encodings;
|
||||
*rule_count = countof(vendor_id_payload_encodings);
|
||||
*rules = encodings;
|
||||
return countof(encodings);
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_header_length, int,
|
||||
private_vendor_id_payload_t *this)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_type, payload_type_t,
|
||||
private_vendor_id_payload_t *this)
|
||||
{
|
||||
return VENDOR_ID;
|
||||
return this->type;
|
||||
}
|
||||
|
||||
METHOD(payload_t, get_next_type, payload_type_t,
|
||||
|
@ -148,7 +158,8 @@ METHOD2(payload_t, vendor_id_payload_t, destroy, void,
|
|||
/*
|
||||
* Described in header
|
||||
*/
|
||||
vendor_id_payload_t *vendor_id_payload_create_data(chunk_t data)
|
||||
vendor_id_payload_t *vendor_id_payload_create_data(payload_type_t type,
|
||||
chunk_t data)
|
||||
{
|
||||
private_vendor_id_payload_t *this;
|
||||
|
||||
|
@ -157,6 +168,7 @@ vendor_id_payload_t *vendor_id_payload_create_data(chunk_t data)
|
|||
.payload_interface = {
|
||||
.verify = _verify,
|
||||
.get_encoding_rules = _get_encoding_rules,
|
||||
.get_header_length = _get_header_length,
|
||||
.get_length = _get_length,
|
||||
.get_next_type = _get_next_type,
|
||||
.set_next_type = _set_next_type,
|
||||
|
@ -167,8 +179,9 @@ vendor_id_payload_t *vendor_id_payload_create_data(chunk_t data)
|
|||
.destroy = _destroy,
|
||||
},
|
||||
.next_payload = NO_PAYLOAD,
|
||||
.payload_length = VENDOR_ID_PAYLOAD_HEADER_LENGTH + data.len,
|
||||
.payload_length = get_header_length(this) + data.len,
|
||||
.data = data,
|
||||
.type = type,
|
||||
);
|
||||
return &this->public;
|
||||
}
|
||||
|
@ -176,7 +189,7 @@ vendor_id_payload_t *vendor_id_payload_create_data(chunk_t data)
|
|||
/*
|
||||
* Described in header
|
||||
*/
|
||||
vendor_id_payload_t *vendor_id_payload_create()
|
||||
vendor_id_payload_t *vendor_id_payload_create(payload_type_t type)
|
||||
{
|
||||
return vendor_id_payload_create_data(chunk_empty);
|
||||
return vendor_id_payload_create_data(type, chunk_empty);
|
||||
}
|
||||
|
|
|
@ -28,12 +28,7 @@ typedef struct vendor_id_payload_t vendor_id_payload_t;
|
|||
#include <encoding/payloads/payload.h>
|
||||
|
||||
/**
|
||||
* Length of a VENDOR ID payload without the VID data in bytes.
|
||||
*/
|
||||
#define VENDOR_ID_PAYLOAD_HEADER_LENGTH 4
|
||||
|
||||
/**
|
||||
* Class representing an IKEv2 VENDOR ID payload.
|
||||
* Class representing an IKEv1/IKEv2 VENDOR ID payload.
|
||||
*
|
||||
* The VENDOR ID payload format is described in RFC section 3.12.
|
||||
*/
|
||||
|
@ -58,18 +53,21 @@ struct vendor_id_payload_t {
|
|||
};
|
||||
|
||||
/**
|
||||
* Creates an empty Vendor ID payload.
|
||||
* Creates an empty Vendor ID payload for IKEv1 or IKEv2.
|
||||
*
|
||||
* @@param type VENDOR_ID or VENDOR_ID_V1
|
||||
* @return vendor ID payload
|
||||
*/
|
||||
vendor_id_payload_t *vendor_id_payload_create();
|
||||
vendor_id_payload_t *vendor_id_payload_create(payload_type_t type);
|
||||
|
||||
/**
|
||||
* Creates a vendor ID payload using a chunk of data
|
||||
*
|
||||
* @param type VENDOR_ID or VENDOR_ID_V1
|
||||
* @param data data to use in vendor ID payload, gets owned by payload
|
||||
* @return vendor ID payload
|
||||
*/
|
||||
vendor_id_payload_t *vendor_id_payload_create_data(chunk_t data);
|
||||
vendor_id_payload_t *vendor_id_payload_create_data(payload_type_t type,
|
||||
chunk_t data);
|
||||
|
||||
#endif /** VENDOR_ID_PAYLOAD_H_ @}*/
|
||||
|
|
|
@ -84,7 +84,7 @@ METHOD(kernel_listener_t, expire, bool,
|
|||
protocol_id_names, proto, ntohl(spi), reqid);
|
||||
if (hard)
|
||||
{
|
||||
job = (job_t*)delete_child_sa_job_create(reqid, proto, spi);
|
||||
job = (job_t*)delete_child_sa_job_create(reqid, proto, spi, hard);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -38,6 +38,8 @@
|
|||
#define BLOCK_THRESHOLD_DEFAULT 5
|
||||
/** length of the secret to use for cookie calculation */
|
||||
#define SECRET_LENGTH 16
|
||||
/** Length of a notify payload header */
|
||||
#define NOTIFY_PAYLOAD_HEADER_LENGTH 8
|
||||
|
||||
typedef struct private_receiver_t private_receiver_t;
|
||||
|
||||
|
@ -134,34 +136,34 @@ struct private_receiver_t {
|
|||
/**
|
||||
* send a notify back to the sender
|
||||
*/
|
||||
static void send_notify(message_t *request, notify_type_t type, chunk_t data)
|
||||
static void send_notify(message_t *request, int major, exchange_type_t exchange,
|
||||
notify_type_t type, chunk_t data)
|
||||
{
|
||||
if (request->get_request(request) &&
|
||||
request->get_exchange_type(request) == IKE_SA_INIT)
|
||||
{
|
||||
message_t *response;
|
||||
host_t *src, *dst;
|
||||
packet_t *packet;
|
||||
ike_sa_id_t *ike_sa_id;
|
||||
ike_sa_id_t *ike_sa_id;
|
||||
message_t *response;
|
||||
host_t *src, *dst;
|
||||
packet_t *packet;
|
||||
|
||||
response = message_create();
|
||||
dst = request->get_source(request);
|
||||
src = request->get_destination(request);
|
||||
response->set_source(response, src->clone(src));
|
||||
response->set_destination(response, dst->clone(dst));
|
||||
response->set_exchange_type(response, request->get_exchange_type(request));
|
||||
response = message_create(major, 0);
|
||||
response->set_exchange_type(response, exchange);
|
||||
response->add_notify(response, FALSE, type, data);
|
||||
dst = request->get_source(request);
|
||||
src = request->get_destination(request);
|
||||
response->set_source(response, src->clone(src));
|
||||
response->set_destination(response, dst->clone(dst));
|
||||
if (major == IKEV2_MAJOR_VERSION)
|
||||
{
|
||||
response->set_request(response, FALSE);
|
||||
response->set_message_id(response, 0);
|
||||
ike_sa_id = request->get_ike_sa_id(request);
|
||||
ike_sa_id->switch_initiator(ike_sa_id);
|
||||
response->set_ike_sa_id(response, ike_sa_id);
|
||||
response->add_notify(response, FALSE, type, data);
|
||||
if (response->generate(response, NULL, &packet) == SUCCESS)
|
||||
{
|
||||
charon->sender->send(charon->sender, packet);
|
||||
response->destroy(response);
|
||||
}
|
||||
}
|
||||
response->set_message_id(response, 0);
|
||||
ike_sa_id = request->get_ike_sa_id(request);
|
||||
ike_sa_id->switch_initiator(ike_sa_id);
|
||||
response->set_ike_sa_id(response, ike_sa_id);
|
||||
if (response->generate(response, NULL, &packet) == SUCCESS)
|
||||
{
|
||||
charon->sender->send(charon->sender, packet);
|
||||
}
|
||||
response->destroy(response);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -269,8 +271,9 @@ static bool drop_ike_sa_init(private_receiver_t *this, message_t *message)
|
|||
half_open = charon->ike_sa_manager->get_half_open_count(
|
||||
charon->ike_sa_manager, NULL);
|
||||
|
||||
/* check for cookies */
|
||||
if (this->cookie_threshold && half_open >= this->cookie_threshold &&
|
||||
/* check for cookies in IKEv2 */
|
||||
if (message->get_major_version(message) == IKEV2_MAJOR_VERSION &&
|
||||
this->cookie_threshold && half_open >= this->cookie_threshold &&
|
||||
!check_cookie(this, message))
|
||||
{
|
||||
u_int32_t now = time_monotonic(NULL);
|
||||
|
@ -282,7 +285,7 @@ static bool drop_ike_sa_init(private_receiver_t *this, message_t *message)
|
|||
message->get_destination(message));
|
||||
DBG2(DBG_NET, "sending COOKIE notify to %H",
|
||||
message->get_source(message));
|
||||
send_notify(message, COOKIE, cookie);
|
||||
send_notify(message, IKEV2_MAJOR_VERSION, IKE_SA_INIT, COOKIE, cookie);
|
||||
chunk_free(&cookie);
|
||||
if (++this->secret_used > COOKIE_REUSE)
|
||||
{
|
||||
|
@ -290,7 +293,7 @@ static bool drop_ike_sa_init(private_receiver_t *this, message_t *message)
|
|||
DBG1(DBG_NET, "generating new cookie secret after %d uses",
|
||||
this->secret_used);
|
||||
memcpy(this->secret_old, this->secret, SECRET_LENGTH);
|
||||
this->rng->get_bytes(this->rng, SECRET_LENGTH, this->secret);
|
||||
this->rng->get_bytes(this->rng, SECRET_LENGTH, this->secret);
|
||||
this->secret_switch = now;
|
||||
this->secret_used = 0;
|
||||
}
|
||||
|
@ -342,9 +345,11 @@ static bool drop_ike_sa_init(private_receiver_t *this, message_t *message)
|
|||
*/
|
||||
static job_requeue_t receive_packets(private_receiver_t *this)
|
||||
{
|
||||
ike_sa_id_t *id;
|
||||
packet_t *packet;
|
||||
message_t *message;
|
||||
status_t status;
|
||||
bool supported = TRUE;
|
||||
|
||||
/* read in a packet */
|
||||
status = charon->socket->receive(charon->socket, &packet);
|
||||
|
@ -371,16 +376,50 @@ static job_requeue_t receive_packets(private_receiver_t *this)
|
|||
}
|
||||
|
||||
/* check IKE major version */
|
||||
if (message->get_major_version(message) != IKE_MAJOR_VERSION)
|
||||
switch (message->get_major_version(message))
|
||||
{
|
||||
DBG1(DBG_NET, "received unsupported IKE version %d.%d from %H, "
|
||||
"sending INVALID_MAJOR_VERSION", message->get_major_version(message),
|
||||
case IKEV2_MAJOR_VERSION:
|
||||
#ifndef USE_IKEV2
|
||||
if (message->get_exchange_type(message) == IKE_SA_INIT &&
|
||||
message->get_request(message))
|
||||
{
|
||||
send_notify(message, IKEV1_MAJOR_VERSION, INFORMATIONAL_V1,
|
||||
INVALID_MAJOR_VERSION, chunk_empty);
|
||||
supported = FALSE;
|
||||
}
|
||||
#endif /* USE_IKEV2 */
|
||||
break;
|
||||
case IKEV1_MAJOR_VERSION:
|
||||
#ifndef USE_IKEV1
|
||||
if (message->get_exchange_type(message) == ID_PROT ||
|
||||
message->get_exchange_type(message) == AGGRESSIVE)
|
||||
{
|
||||
send_notify(message, IKEV2_MAJOR_VERSION, INFORMATIONAL,
|
||||
INVALID_MAJOR_VERSION, chunk_empty);
|
||||
supported = FALSE;
|
||||
}
|
||||
#endif /* USE_IKEV1 */
|
||||
break;
|
||||
default:
|
||||
#ifdef USE_IKEV2
|
||||
send_notify(message, IKEV2_MAJOR_VERSION, INFORMATIONAL,
|
||||
INVALID_MAJOR_VERSION, chunk_empty);
|
||||
#endif /* USE_IKEV2 */
|
||||
#ifdef USE_IKEV1
|
||||
send_notify(message, IKEV1_MAJOR_VERSION, INFORMATIONAL_V1,
|
||||
INVALID_MAJOR_VERSION, chunk_empty);
|
||||
#endif /* USE_IKEV1 */
|
||||
supported = FALSE;
|
||||
break;
|
||||
}
|
||||
if (!supported)
|
||||
{
|
||||
DBG1(DBG_NET, "received unsupported IKE version %d.%d from %H, sending "
|
||||
"INVALID_MAJOR_VERSION", message->get_major_version(message),
|
||||
message->get_minor_version(message), packet->get_source(packet));
|
||||
send_notify(message, INVALID_MAJOR_VERSION, chunk_empty);
|
||||
message->destroy(message);
|
||||
return JOB_REQUEUE_DIRECT;
|
||||
}
|
||||
|
||||
if (message->get_request(message) &&
|
||||
message->get_exchange_type(message) == IKE_SA_INIT)
|
||||
{
|
||||
|
@ -390,6 +429,18 @@ static job_requeue_t receive_packets(private_receiver_t *this)
|
|||
return JOB_REQUEUE_DIRECT;
|
||||
}
|
||||
}
|
||||
if (message->get_exchange_type(message) == ID_PROT ||
|
||||
message->get_exchange_type(message) == AGGRESSIVE)
|
||||
{
|
||||
id = message->get_ike_sa_id(message);
|
||||
if (id->get_responder_spi(id) == 0 &&
|
||||
drop_ike_sa_init(this, message))
|
||||
{
|
||||
message->destroy(message);
|
||||
return JOB_REQUEUE_DIRECT;
|
||||
}
|
||||
}
|
||||
|
||||
if (this->receive_delay)
|
||||
{
|
||||
if (this->receive_delay_type == 0 ||
|
||||
|
|
|
@ -273,11 +273,11 @@ static job_requeue_t initiate(private_android_service_t *this)
|
|||
hostname, IKEV2_UDP_PORT);
|
||||
ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
|
||||
|
||||
peer_cfg = peer_cfg_create("android", 2, ike_cfg, CERT_SEND_IF_ASKED,
|
||||
peer_cfg = peer_cfg_create("android", IKEV2, ike_cfg, CERT_SEND_IF_ASKED,
|
||||
UNIQUE_REPLACE, 1, /* keyingtries */
|
||||
36000, 0, /* rekey 10h, reauth none */
|
||||
600, 600, /* jitter, over 10min */
|
||||
TRUE, 0, /* mobike, DPD */
|
||||
TRUE, FALSE, 0, /* mobike, aggressive, DPD */
|
||||
host_create_from_string("0.0.0.0", 0) /* virt */,
|
||||
NULL, FALSE, NULL, NULL); /* pool, mediation */
|
||||
|
||||
|
@ -300,12 +300,17 @@ static job_requeue_t initiate(private_android_service_t *this)
|
|||
0, "255.255.255.255", 65535);
|
||||
child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
|
||||
peer_cfg->add_child_cfg(peer_cfg, child_cfg);
|
||||
/* get an additional reference because initiate consumes one */
|
||||
child_cfg->get_ref(child_cfg);
|
||||
|
||||
/* get us an IKE_SA */
|
||||
ike_sa = charon->ike_sa_manager->checkout_by_config(charon->ike_sa_manager,
|
||||
peer_cfg);
|
||||
if (!ike_sa)
|
||||
{
|
||||
peer_cfg->destroy(peer_cfg);
|
||||
send_status(this, VPN_ERROR_CONNECTION_FAILED);
|
||||
return JOB_REQUEUE_NONE;
|
||||
}
|
||||
|
||||
if (!ike_sa->get_peer_cfg(ike_sa))
|
||||
{
|
||||
ike_sa->set_peer_cfg(ike_sa, peer_cfg);
|
||||
|
@ -318,6 +323,8 @@ static job_requeue_t initiate(private_android_service_t *this)
|
|||
/* confirm that we received the request */
|
||||
send_status(this, i);
|
||||
|
||||
/* get an additional reference because initiate consumes one */
|
||||
child_cfg->get_ref(child_cfg);
|
||||
if (ike_sa->initiate(ike_sa, child_cfg, 0, NULL, NULL) != SUCCESS)
|
||||
{
|
||||
DBG1(DBG_CFG, "failed to initiate tunnel");
|
||||
|
|
|
@ -176,9 +176,9 @@ METHOD(listener_t, ike_updown, bool,
|
|||
|
||||
METHOD(listener_t, message_hook, bool,
|
||||
private_duplicheck_listener_t *this, ike_sa_t *ike_sa,
|
||||
message_t *message, bool incoming)
|
||||
message_t *message, bool incoming, bool plain)
|
||||
{
|
||||
if (incoming && !message->get_request(message))
|
||||
if (incoming && plain && !message->get_request(message))
|
||||
{
|
||||
identification_t *id;
|
||||
entry_t *entry;
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
typedef struct eap_aka_peer_t eap_aka_peer_t;
|
||||
|
||||
#include <sa/authenticators/eap/eap_method.h>
|
||||
#include <sa/eap/eap_method.h>
|
||||
|
||||
/**
|
||||
* EAP-AKA peer implementation.
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
typedef struct eap_aka_server_t eap_aka_server_t;
|
||||
|
||||
#include <sa/authenticators/eap/eap_method.h>
|
||||
#include <sa/eap/eap_method.h>
|
||||
|
||||
/**
|
||||
* EAP-AKA server implementation.
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
typedef struct eap_gtc_t eap_gtc_t;
|
||||
|
||||
#include <sa/authenticators/eap/eap_method.h>
|
||||
#include <sa/eap/eap_method.h>
|
||||
|
||||
/**
|
||||
* Implementation of the eap_method_t interface using EAP-GTC.
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
typedef struct eap_identity_t eap_identity_t;
|
||||
|
||||
#include <sa/authenticators/eap/eap_method.h>
|
||||
#include <sa/eap/eap_method.h>
|
||||
|
||||
/**
|
||||
* Implementation of the eap_method_t interface using EAP Identity.
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
typedef struct eap_md5_t eap_md5_t;
|
||||
|
||||
#include <sa/authenticators/eap/eap_method.h>
|
||||
#include <sa/eap/eap_method.h>
|
||||
|
||||
/**
|
||||
* Implementation of the eap_method_t interface using EAP-MD5 (CHAP).
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
typedef struct eap_mschapv2_t eap_mschapv2_t;
|
||||
|
||||
#include <sa/authenticators/eap/eap_method.h>
|
||||
#include <sa/eap/eap_method.h>
|
||||
|
||||
/**
|
||||
* Implementation of the eap_method_t interface using EAP-MS-CHAPv2.
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue