Merge lp:~midauth-pisa-devs/hipl/midauth-firewall into lp:hipl

Proposed by René Hummen
Status: Superseded
Proposed branch: lp:~midauth-pisa-devs/hipl/midauth-firewall
Merge into: lp:hipl
Diff against target: 2333 lines (+1286/-550)
20 files modified
Makefile.am (+6/-3)
firewall/conntrack.c (+88/-24)
firewall/firewall.c (+5/-34)
firewall/firewall.h (+0/-1)
firewall/firewall_defines.h (+10/-3)
firewall/main.c (+3/-10)
firewall/midauth.c (+229/-400)
firewall/midauth.h (+10/-49)
firewall/pisa.h (+2/-0)
firewall/rewrite.c (+380/-0)
firewall/rewrite.h (+39/-0)
lib/tool/checksum.c (+26/-23)
lib/tool/checksum.h (+5/-2)
packaging/openwrt/hipl/files/hipfw.init (+1/-1)
test/check_firewall.c (+2/-0)
test/firewall/midauth.c (+298/-0)
test/firewall/rewrite.c (+151/-0)
test/firewall/test_suites.h (+2/-0)
test/mocks.c (+26/-0)
test/mocks.h (+3/-0)
To merge this branch: bzr merge lp:~midauth-pisa-devs/hipl/midauth-firewall
Reviewer Review Type Date Requested Status
Diego Biurrun Needs Fixing
Review via email: mp+79811@code.launchpad.net

This proposal has been superseded by a proposal from 2011-10-25.

Description of the change

This branch re-implements the hipfw-related part of http://tools.ietf.org/html/draft-heer-hip-middle-auth-02.

Short intro to HIP middlebox authentication:
1) The firewall intercepts R1, I2, U1 and U2 messages and adds a nonce that needs to be echoed back to the firewall by the respective end-host in the signed part of the reply. This enables the firewall to evaluate the freshness of the exchange.
2) In order to mitigate DoS attacks targeting the signature verification at the firewall, the nonce is additionally used as the input for a puzzle that the end-host needs to solve and send back to the firewall in the reply as well.

To post a comment you must log in.
Revision history for this message
Diego Biurrun (diego-biurrun) wrote :
Download full text (14.4 KiB)

 review needs-fixing

On Wed, Oct 19, 2011 at 01:17:30PM +0000, René Hummen wrote:
>
> For more details, see:
> https://code.launchpad.net/~midauth-pisa-devs/hipl/midauth-firewall/+merge/79811
>
> This branch re-implements the hipfw-related part of http://tools.ietf.org/html/draft-heer-hip-middle-auth-02.
>
> Short intro to HIP middlebox authentication:
> 1) The firewall intercepts R1, I2, U1 and U2 messages and adds a nonce that needs to be echoed back to the firewall by the respective end-host in the signed part of the reply. This enables the firewall to evaluate the freshness of the exchange.
> 2) In order to mitigate DoS attacks targeting the signature verification at the firewall, the nonce is additionally used as the input for a puzzle that the end-host needs to solve and send back to the firewall in the reply as well.
> --
> https://code.launchpad.net/~midauth-pisa-devs/hipl/midauth-firewall/+merge/79811
> Your team HIPL core team is requested to review the proposed merge of lp:~midauth-pisa-devs/hipl/midauth-firewall into lp:hipl.

> --- Makefile.am 2011-10-17 18:14:10 +0000
> +++ Makefile.am 2011-10-19 13:13:48 +0000
> @@ -253,7 +256,7 @@
>
> -test_check_firewall_LDFLAGS = -ldl
> +test_check_firewall_LDFLAGS = -ldl -z muldefs

We have solved this differently elsewhere by #including the .c file to
unit-test static functions.

> --- firewall/conntrack.c 2011-10-19 09:51:41 +0000
> +++ firewall/conntrack.c 2011-10-19 13:13:48 +0000
> @@ -998,7 +998,7 @@
> *
> * @param common the hip packet to be verified
> * @param tuple the corresponding connection tuple
> - * @return 1 for valid packets, 0 otherwise
> + * @return 0 for valid packets, 1 otherwise
> */
> static int hip_fw_verify_packet(struct hip_common *const common,
> const struct tuple *const tuple)

This looks like a change that could be separated.

> @@ -1526,14 +1565,28 @@
>
> } else if (esp_info && seq && ack) {
> - if (!tuple) {
> + if (tuple && tuple->direction == ORIGINAL_DIR) {
> + other_dir = &tuple->connection->reply;
> + } else if (tuple) {
> + other_dir = &tuple->connection->original;
> + } else {
> HIP_ERROR("Insufficient stored state to process UPDATE\n");
> return 0;
> }

tuple is checked twice.

> - if (!hip_fw_verify_packet(common, tuple)) {
> + if (!hipfw_midauth_verify_challenge(ctx, other_dir->midauth_nonce)) {
> + HIP_ERROR("failed to verify midauth challenge\n");
> + return 0;
> + }

0 is returned in case of error?

> @@ -1543,14 +1596,29 @@
> } else if (ack) {
> - if (!tuple) {
> + if (tuple && tuple->direction == ORIGINAL_DIR) {
> + other_dir = &tuple->connection->reply;
> + } else if (tuple) {
> + other_dir = &tuple->connection->original;
> + } else {
> HIP_ERROR("Insufficient stored state to process UPDATE\n");
> return 0;
> }

another redundant check

Oh, this code seems to be completely duplicated.

> @@ -1842,7 +1910,7 @@
>
> -#ifdef CONFIG_HIP_MIDAUTH
...

review: Needs Fixing
6097. By René Hummen

address diego's comments of the merge proposal

6098. By René Hummen

add missing doxygen comment

6099. By René Hummen

remove double check of tuple

Revision history for this message
Diego Biurrun (diego-biurrun) wrote :
Download full text (5.6 KiB)

On Tue, Oct 25, 2011 at 02:28:06PM +0200, René Hummen wrote:
> On 20.10.2011, at 14:15, Diego Biurrun wrote:
> > On Wed, Oct 19, 2011 at 01:17:30PM +0000, René Hummen wrote:
> >
> >> --- Makefile.am 2011-10-17 18:14:10 +0000
> >> +++ Makefile.am 2011-10-19 13:13:48 +0000
> >> @@ -253,7 +256,7 @@
> >>
> >> -test_check_firewall_LDFLAGS = -ldl
> >> +test_check_firewall_LDFLAGS = -ldl -z muldefs
> >
> > We have solved this differently elsewhere by #including the .c file to
> > unit-test static functions.
>
> This has been discussed previously on the list:
> http://www.freelists.org/post/hipl-dev/Mock-functions-for-hipl-unit-tests

But we currently don't favor that solution. If that needs changing,
it's a topic for a separate merge request and would need to be changed
in all places.

> >> @@ -1526,14 +1565,28 @@
> >>
> >> } else if (esp_info && seq && ack) {
> >> - if (!tuple) {
> >> + if (tuple && tuple->direction == ORIGINAL_DIR) {
> >> + other_dir = &tuple->connection->reply;
> >> + } else if (tuple) {
> >> + other_dir = &tuple->connection->original;
> >> + } else {
> >> HIP_ERROR("Insufficient stored state to process UPDATE\n");
> >> return 0;
> >> }
> >
> > tuple is checked twice.
>
> Yes, but I need to be sure that tuple exists when accessing its
> members in the body of the else if.

So? That does not imply you need to check "tuple" twice, just nest the
ifs, witness:

  if (tuple) {
      if (tuple->direction == ORIGINAL_DIR) {
          other_dir = &tuple->connection->reply;
      } else {
          other_dir = &tuple->connection->original;
  } else {
     HIP_ERROR("Insufficient stored state to process UPDATE\n");
     return 0;
 }

> >> - if (!hip_fw_verify_packet(common, tuple)) {
> >> + if (!hipfw_midauth_verify_challenge(ctx, other_dir->midauth_nonce)) {
> >> + HIP_ERROR("failed to verify midauth challenge\n");
> >> + return 0;
> >> + }
> >
> > 0 is returned in case of error?
>
> Yes, firewall/conntrack.c does not use the same semantics for return
> values compared to the rest of the code.

Then fix conntrack.c and don't make the code consistently inconsistent,
cf. the boyscout rule.

> >> @@ -1543,14 +1596,29 @@
> >> } else if (ack) {
> >> - if (!tuple) {
> >> + if (tuple && tuple->direction == ORIGINAL_DIR) {
> >> + other_dir = &tuple->connection->reply;
> >> + } else if (tuple) {
> >> + other_dir = &tuple->connection->original;
> >> + } else {
> >> HIP_ERROR("Insufficient stored state to process UPDATE\n");
> >> return 0;
> >> }
> >
> > another redundant check
> >
> > Oh, this code seems to be completely duplicated.
>
> Yes, but I didn't see the need for a new function as this code is
> specific for updates and only used twice.

There is no such thing as "only" used twice, code duplication
is code duplication is code duplication :)

> >> --- firewall/firewall.c 2011-08-16 07:49:25 +0000
> >> +++ firewall/firewall.c 2011-10-19 13:13:48 +0000
> >> @@ -76,12 +76,13 @@
> >> #include "lib...

Read more...

6100. By René Hummen

remove read-only variable 'found'

Revision history for this message
René Hummen (rene-hummen) wrote :
Download full text (4.7 KiB)

On 25.10.2011, at 15:24, Diego Biurrun wrote:
> On Tue, Oct 25, 2011 at 02:28:06PM +0200, René Hummen wrote:
>> On 20.10.2011, at 14:15, Diego Biurrun wrote:
>>> On Wed, Oct 19, 2011 at 01:17:30PM +0000, René Hummen wrote:
>>>
>>>> --- Makefile.am 2011-10-17 18:14:10 +0000
>>>> +++ Makefile.am 2011-10-19 13:13:48 +0000
>>>> @@ -253,7 +256,7 @@
>>>>
>>>> -test_check_firewall_LDFLAGS = -ldl
>>>> +test_check_firewall_LDFLAGS = -ldl -z muldefs
>>>
>>> We have solved this differently elsewhere by #including the .c file to
>>> unit-test static functions.
>>
>> This has been discussed previously on the list:
>> http://www.freelists.org/post/hipl-dev/Mock-functions-for-hipl-unit-tests
>
> But we currently don't favor that solution. If that needs changing,
> it's a topic for a separate merge request and would need to be changed
> in all places.

The change was necessary in order to comply with our unit-test for new code policy as unit-tests would otherwise not link correctly. The only other option I see right now is to merge the code without unit-tests.

>>>> - if (!hip_fw_verify_packet(common, tuple)) {
>>>> + if (!hipfw_midauth_verify_challenge(ctx, other_dir->midauth_nonce)) {
>>>> + HIP_ERROR("failed to verify midauth challenge\n");
>>>> + return 0;
>>>> + }
>>>
>>> 0 is returned in case of error?
>>
>> Yes, firewall/conntrack.c does not use the same semantics for return
>> values compared to the rest of the code.
>
> Then fix conntrack.c and don't make the code consistently inconsistent,
> cf. the boyscout rule.

This would further increase the (already huge) merge request. It's definitely out of focus of this branch.

>>>> --- firewall/firewall.c 2011-08-16 07:49:25 +0000
>>>> +++ firewall/firewall.c 2011-10-19 13:13:48 +0000
>>>> @@ -76,12 +76,13 @@
>>>> #include "lib/core/prefix.h"
>>>> #include "lib/core/util.h"
>>>> #include "hipd/hipd.h"
>>>> -#include "config.h"
>>>> #include "cache.h"
>>>> #include "common_types.h"
>>>> +#include "config.h"
>>>> #include "conntrack.h"
>>>> #include "esp_prot_api.h"
>>>> #include "esp_prot_conntrack.h"
>>>> +#include "firewall.h"
>>>> #include "firewall_control.h"
>>>> #include "firewall_defines.h"
>>>> #include "helpers.h"
>>>> @@ -90,9 +91,9 @@
>>>> #include "pisa.h"
>>>> #include "port_bindings.h"
>>>> #include "reinject.h"
>>>> +#include "rewrite.h"
>>>> #include "rule_management.h"
>>>> #include "user_ipsec_api.h"
>>>> -#include "firewall.h"
>>>
>>> The ordering is actually done on purpose. config.h is not in the same
>>> directory, same as the other #includes with directory prefixes and
>>> firewall.h directly "belongs" to firewall.c, so it made sense at the
>>> time to put it last and list all dependencies before. I have this
>>> feeling in the back of my head that the latter solved some real issue.
>>
>> 'make alltests' runs successfully. So, what exactly is your suggestion?
>
> My suggestion is not to change the #include ordering.

If the order of the includes is relevant, then there probably is some other problem in the header files. Everything is compiling nicely now. So I don't know what kind of issue you are tal...

Read more...

Revision history for this message
Diego Biurrun (diego-biurrun) wrote :
Download full text (5.1 KiB)

On Tue, Oct 25, 2011 at 02:35:31PM +0000, René Hummen wrote:
> On 25.10.2011, at 15:24, Diego Biurrun wrote:
> > On Tue, Oct 25, 2011 at 02:28:06PM +0200, René Hummen wrote:
> >> On 20.10.2011, at 14:15, Diego Biurrun wrote:
> >>> On Wed, Oct 19, 2011 at 01:17:30PM +0000, René Hummen wrote:
> >>>
> >>>> --- Makefile.am 2011-10-17 18:14:10 +0000
> >>>> +++ Makefile.am 2011-10-19 13:13:48 +0000
> >>>> @@ -253,7 +256,7 @@
> >>>>
> >>>> -test_check_firewall_LDFLAGS = -ldl
> >>>> +test_check_firewall_LDFLAGS = -ldl -z muldefs
> >>>
> >>> We have solved this differently elsewhere by #including the .c file to
> >>> unit-test static functions.
> >>
> >> This has been discussed previously on the list:
> >> http://www.freelists.org/post/hipl-dev/Mock-functions-for-hipl-unit-tests
> >
> > But we currently don't favor that solution. If that needs changing,
> > it's a topic for a separate merge request and would need to be changed
> > in all places.
>
> The change was necessary in order to comply with our unit-test for new
> code policy as unit-tests would otherwise not link correctly. The only
> other option I see right now is to merge the code without unit-tests.

No, the change is not necessary. As I said before, we have solved this
differently elsewhere by #including the .c file to unit-test static
functions. Changing this is outside the scope of this merge request
and it is not at all clear that a GNU-specific linker flag is the
better solution.

> >>>> - if (!hip_fw_verify_packet(common, tuple)) {
> >>>> + if (!hipfw_midauth_verify_challenge(ctx, other_dir->midauth_nonce)) {
> >>>> + HIP_ERROR("failed to verify midauth challenge\n");
> >>>> + return 0;
> >>>> + }
> >>>
> >>> 0 is returned in case of error?
> >>
> >> Yes, firewall/conntrack.c does not use the same semantics for return
> >> values compared to the rest of the code.
> >
> > Then fix conntrack.c and don't make the code consistently inconsistent,
> > cf. the boyscout rule.
>
> This would further increase the (already huge) merge request. It's
> definitely out of focus of this branch.

Nobody claims it has to be done as part of this merge request; it's
easy enough to fix separately. If you are worried about the size of
this merge request, that's all the more reason not to make unrelated
changes to conntrack.c.

> >>>> --- firewall/firewall.c 2011-08-16 07:49:25 +0000
> >>>> +++ firewall/firewall.c 2011-10-19 13:13:48 +0000
> >>>> @@ -76,12 +76,13 @@
> >>>> #include "lib/core/prefix.h"
> >>>> #include "lib/core/util.h"
> >>>> #include "hipd/hipd.h"
> >>>> -#include "config.h"
> >>>> #include "cache.h"
> >>>> #include "common_types.h"
> >>>> +#include "config.h"
> >>>> #include "conntrack.h"
> >>>> #include "esp_prot_api.h"
> >>>> #include "esp_prot_conntrack.h"
> >>>> +#include "firewall.h"
> >>>> #include "firewall_control.h"
> >>>> #include "firewall_defines.h"
> >>>> #include "helpers.h"
> >>>> @@ -90,9 +91,9 @@
> >>>> #include "pisa.h"
> >>>> #include "port_bindings.h"
> >>>> #include "reinject.h"
> >>>> +#include "rewrite.h"
> >>>> #include "rule_management.h"
> >>>> #include "user_ipsec_api.h"
> >>>> -#i...

Read more...

Revision history for this message
Christof Mroz (christof-mroz) wrote :

On 25.10.2011 16:35, René Hummen wrote:
>>>>> + if (!found) {
>>>>> + HIP_ERROR("CHALLENGE_RESPONSE found, but no matching nonce\n");
>>>>> + return ignore_missing_challenge_response ? 1 : 0;
>>>>> + }
>>>>> +
>>>>> + return found ? 1 : 0;
>>>>
>>>> You just checked found, no need to do it again.
>>>
>>> I guess that this has been done to ensure correct type conversion from
>>> bool to int.
>>
>> Read the code again, it's nonsense, "found" is initialized once and
>> never set again.
>
> You're right. I removed it and changed it to
>
>>>>> return ignore_missing_challenge_response ? 1 : 0;

This doesn't look correct... you signal failure even though the
CHALLENGE_RESPONSE was found? I think Diego meant to simply write

return 1;

Because we know that found is true at this point.

Revision history for this message
Christof Mroz (christof-mroz) wrote :

On 25.10.2011 23:02, Diego Biurrun wrote:
> On Tue, Oct 25, 2011 at 02:35:31PM +0000, René Hummen wrote:
>> On 25.10.2011, at 15:24, Diego Biurrun wrote:
>>> On Tue, Oct 25, 2011 at 02:28:06PM +0200, René Hummen wrote:
>>>> On 20.10.2011, at 14:15, Diego Biurrun wrote:
>>>>> On Wed, Oct 19, 2011 at 01:17:30PM +0000, René Hummen wrote:
>>>>>
>>>>>> --- Makefile.am 2011-10-17 18:14:10 +0000
>>>>>> +++ Makefile.am 2011-10-19 13:13:48 +0000
>>>>>> @@ -253,7 +256,7 @@
>>>>>>
>>>>>> -test_check_firewall_LDFLAGS = -ldl
>>>>>> +test_check_firewall_LDFLAGS = -ldl -z muldefs
>>>>>
>>>>> We have solved this differently elsewhere by #including the .c file to
>>>>> unit-test static functions.
>>>>
>>>> This has been discussed previously on the list:
>>>> http://www.freelists.org/post/hipl-dev/Mock-functions-for-hipl-unit-tests
>>>
>>> But we currently don't favor that solution. If that needs changing,
>>> it's a topic for a separate merge request and would need to be changed
>>> in all places.
>>
>> The change was necessary in order to comply with our unit-test for new
>> code policy as unit-tests would otherwise not link correctly. The only
>> other option I see right now is to merge the code without unit-tests.
>
> No, the change is not necessary. As I said before, we have solved
> this differently elsewhere by #including the .c file to unit-test
> static functions.

Including the .c file allows you to access static identifiers in unit
tests, but the libipq problem (see referenced thread) is a different one.
Apparently, Hendrik already tried to mimic the other (working) tests
already without success.

> Changing this is outside the scope of this merge request and it is not
> at all clear that a GNU-specific linker flag is the better solution.

I'd really appreciate a hint... the best I could come up with was the
LD_PRELOAD solution (see referenced thread), which AFAIK was invented
for cases like these: The need to intercept library calls.

You'd have to build a separate shared object to be linked with the tests
at runtime though, which is no rocket science but would require changes
and debugging in the build system nevertheless.

If anybody is willing to implement it anyway, I'd happily elaborate on
that idea as it would allow us to constrain the mock functions to those
tests actually using them.

Revision history for this message
Diego Biurrun (diego-biurrun) wrote :

On Tue, Oct 25, 2011 at 11:43:43PM +0200, Christof Mroz wrote:
> On 25.10.2011 23:02, Diego Biurrun wrote:
> >On Tue, Oct 25, 2011 at 02:35:31PM +0000, René Hummen wrote:
> >>On 25.10.2011, at 15:24, Diego Biurrun wrote:
> >>>On Tue, Oct 25, 2011 at 02:28:06PM +0200, René Hummen wrote:
> >>>>On 20.10.2011, at 14:15, Diego Biurrun wrote:
> >>>>>On Wed, Oct 19, 2011 at 01:17:30PM +0000, René Hummen wrote:
> >>>>>
> >>>>>>--- Makefile.am 2011-10-17 18:14:10 +0000
> >>>>>>+++ Makefile.am 2011-10-19 13:13:48 +0000
> >>>>>>@@ -253,7 +256,7 @@
> >>>>>>
> >>>>>>-test_check_firewall_LDFLAGS = -ldl
> >>>>>>+test_check_firewall_LDFLAGS = -ldl -z muldefs
> >>>>>
> >>>>>We have solved this differently elsewhere by #including the .c file to
> >>>>>unit-test static functions.
> >>>>
> >>>>This has been discussed previously on the list:
> >>>> http://www.freelists.org/post/hipl-dev/Mock-functions-for-hipl-unit-tests
> >>>
> >>>But we currently don't favor that solution. If that needs changing,
> >>>it's a topic for a separate merge request and would need to be changed
> >>>in all places.
> >>
> >>The change was necessary in order to comply with our unit-test for new
> >>code policy as unit-tests would otherwise not link correctly. The only
> >>other option I see right now is to merge the code without unit-tests.
> >
> >No, the change is not necessary. As I said before, we have solved
> >this differently elsewhere by #including the .c file to unit-test
> >static functions.
>
> Including the .c file allows you to access static identifiers in
> unit tests, but the libipq problem (see referenced thread) is a
> different one.
> Apparently, Hendrik already tried to mimic the other (working) tests
> already without success.

I'd like to know what is failing exactly and how before making
a judgement here.

Diego

Revision history for this message
Christof Mroz (christof-mroz) wrote :

Forgot to CC launchpad.

-------- Original Message --------
Subject: [hipl-dev] Re: [Merge]
lp:~midauth-pisa-devs/hipl/midauth-firewall into lp:hipl
Date: Wed, 26 Oct 2011 23:16:18 +0200
From: Christof Mroz <email address hidden>
Reply-To: <email address hidden>
To: <email address hidden>

On 26.10.2011 22:57, Diego Biurrun wrote:
> On Tue, Oct 25, 2011 at 11:43:43PM +0200, Christof Mroz wrote:
>> On 25.10.2011 23:02, Diego Biurrun wrote:
>>> On Tue, Oct 25, 2011 at 02:35:31PM +0000, René Hummen wrote:
>>>> On 25.10.2011, at 15:24, Diego Biurrun wrote:
>>>>> On Tue, Oct 25, 2011 at 02:28:06PM +0200, René Hummen wrote:
>>>>>> On 20.10.2011, at 14:15, Diego Biurrun wrote:
>>>>>>> On Wed, Oct 19, 2011 at 01:17:30PM +0000, René Hummen wrote:
>>>>>>>
>>>>>>>> --- Makefile.am 2011-10-17 18:14:10 +0000
>>>>>>>> +++ Makefile.am 2011-10-19 13:13:48 +0000
>>>>>>>> @@ -253,7 +256,7 @@
>>>>>>>>
>>>>>>>> -test_check_firewall_LDFLAGS = -ldl
>>>>>>>> +test_check_firewall_LDFLAGS = -ldl -z muldefs
>>>>>>>
>>>>>>> We have solved this differently elsewhere by #including the .c file to
>>>>>>> unit-test static functions.
>>>>>>
>>>>>> This has been discussed previously on the list:
>>>>>> http://www.freelists.org/post/hipl-dev/Mock-functions-for-hipl-unit-tests
>>>>>
>>>>> But we currently don't favor that solution. If that needs changing,
>>>>> it's a topic for a separate merge request and would need to be changed
>>>>> in all places.
>>>>
>>>> The change was necessary in order to comply with our unit-test for new
>>>> code policy as unit-tests would otherwise not link correctly. The only
>>>> other option I see right now is to merge the code without unit-tests.
>>>
>>> No, the change is not necessary. As I said before, we have solved
>>> this differently elsewhere by #including the .c file to unit-test
>>> static functions.
>>
>> Including the .c file allows you to access static identifiers in
>> unit tests, but the libipq problem (see referenced thread) is a
>> different one.
>> Apparently, Hendrik already tried to mimic the other (working) tests
>> already without success.
>
> I'd like to know what is failing exactly and how before making
> a judgement here.

See the referenced thread for details, but essentially we need to mock
ipq_get_packet() which is usually provided by linking -lipq.
Strangely, while our usual approach (simply exporting a function with
exact same signature in an object file) works for libc, it does fail
with a "multiple definition" error for explicitly linked-in libs like
libipq.
Making libipq just as "magic" as libc would solve the problem, if that's
possible.

Revision history for this message
Diego Biurrun (diego-biurrun) wrote :

On Sat, Oct 22, 2011 at 02:44:31PM +0200, Christof Mroz wrote:
> On 22.10.2011 13:36, Diego Biurrun wrote:
> >>>>+static void *rebase(const void *const field,
> >>>>+ const void *const old,
> >>>>+ void *const new)
> >>>>+{
> >>>>+ return (char *) new + ((const char *) field - (const char *) old);
> >>>
> >>>pointless parentheses
> >>
> >>(field - old) is usually a low "number", if we treat pointers
> >>numerically, while (new + field) is usually big. Could even be
> >>bigger than the machine pointer size, especially considering the
> >>gamut of devices we support. Are you sure the compiler will do the
> >>right thing here if we drop the parentheses?
> >
> >I do not believe that parentheses work in the way you hope for here.
> >I would assume that the compiler is free to evaluate the operations
> >in arbitrary order. Have you verified that the behavior you seem to
> >be relying on is actually implemented like you expect?
>
> Good question. Admittedly I didn't know about the details so far
> either, so I dug around a bit and Example 6 in section 5.1.2.3 of
> [1] (page 15) seems to answer our question. It states:
> >On a machine in which overflow silently generates some value and where
> >positive and negative overflows cancel, the above expression statement
> >can be rewritten by the implementation in any of the above ways
> >because the same result will occur.
> This is the case on x86 for example, meaning that we could safely
> overflow around as long as we don't care about the bits outside our
> machine word, on this platform. I can show an example if you don't
> believe me.
>
> On the other hand, it is stated that (in reference to an example
> involving addition/subtraction):
> >On a machine in which overflows produce an explicit trap and in which
> >the range of values representable by an int is [32768, +32767], the
> >implementation cannot rewrite this expression as [...]
> So by keeping the parentheses, we can ensure that our code runs on
> this kind of platform too, right?
>
> [1] http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf

The standard is quoted - we're taking this to a whole new level :)

I would suggest a comment to explain the parentheses in this case.
Very few people working on HIPL will be aware of why they might be
needed.

> >>>>+ while ((current = hip_get_next_param_readwrite(hip, current))) {
> >>>>+ if (hip_get_param_type(current)>= param_type) {
> >>>>+ uint8_t *const splice = (uint8_t *const) current;
> >>>>+
> >>>>+ memmove(splice + param_len, splice, end - splice);
> >>>>+ out = splice;
> >>>>+ break;
> >>>
> >>>The splice variable looks unnecessary.
> >>
> >>Personally, I found the number of casts distracting.
> >
> >If I did not misread the code, then no casts should be necessary.
>
> It's true that memmove() accepts void*, but current must be
> re-interpreted as a uint8_t buffer for the pointer arithmetic to
> work correctly (since param_len is given as a byte count).

Whatever you prefer then.

Diego

Revision history for this message
Diego Biurrun (diego-biurrun) wrote :

On Wed, Oct 26, 2011 at 11:16:18PM +0200, Christof Mroz wrote:
> On 26.10.2011 22:57, Diego Biurrun wrote:
> >On Tue, Oct 25, 2011 at 11:43:43PM +0200, Christof Mroz wrote:
> >>On 25.10.2011 23:02, Diego Biurrun wrote:
> >>>On Tue, Oct 25, 2011 at 02:35:31PM +0000, René Hummen wrote:
> >>>>On 25.10.2011, at 15:24, Diego Biurrun wrote:
> >>>>>On Tue, Oct 25, 2011 at 02:28:06PM +0200, René Hummen wrote:
> >>>>>>On 20.10.2011, at 14:15, Diego Biurrun wrote:
> >>>>>>>On Wed, Oct 19, 2011 at 01:17:30PM +0000, René Hummen wrote:
> >>>>>>>
> >>>>>>>>--- Makefile.am 2011-10-17 18:14:10 +0000
> >>>>>>>>+++ Makefile.am 2011-10-19 13:13:48 +0000
> >>>>>>>>@@ -253,7 +256,7 @@
> >>>>>>>>
> >>>>>>>>-test_check_firewall_LDFLAGS = -ldl
> >>>>>>>>+test_check_firewall_LDFLAGS = -ldl -z muldefs
> >>>>>>>
> >>>>>>>We have solved this differently elsewhere by #including the .c file to
> >>>>>>>unit-test static functions.
> >>>>>>
> >>>>>>This has been discussed previously on the list:
> >>>>>> http://www.freelists.org/post/hipl-dev/Mock-functions-for-hipl-unit-tests
> >>>>>
> >>>>>But we currently don't favor that solution. If that needs changing,
> >>>>>it's a topic for a separate merge request and would need to be changed
> >>>>>in all places.
> >>>>
> >>>>The change was necessary in order to comply with our unit-test for new
> >>>>code policy as unit-tests would otherwise not link correctly. The only
> >>>>other option I see right now is to merge the code without unit-tests.
> >>>
> >>>No, the change is not necessary. As I said before, we have solved
> >>>this differently elsewhere by #including the .c file to unit-test
> >>>static functions.
> >>
> >>Including the .c file allows you to access static identifiers in
> >>unit tests, but the libipq problem (see referenced thread) is a
> >>different one.
> >>Apparently, Hendrik already tried to mimic the other (working) tests
> >>already without success.
> >
> >I'd like to know what is failing exactly and how before making
> >a judgement here.
>
> See the referenced thread for details, but essentially we need to
> mock ipq_get_packet() which is usually provided by linking -lipq.

What I don't get is the reason why we need to mock that function
in the first place. Probably I am missing something totally
obvious.

Diego

Revision history for this message
Christof Mroz (christof-mroz) wrote :

On 27.10.2011 00:20, Diego Biurrun wrote:
>> See the referenced thread for details, but essentially we need to
>> mock ipq_get_packet() which is usually provided by linking -lipq.
>
> What I don't get is the reason why we need to mock that function
> in the first place. Probably I am missing something totally
> obvious.

Looking at the patch and judging from my memory, I think it's called by
hipfw_init_context().
On the one hand, much of the firewall code makes heavy direct use of ipq
structures (they're even part of the context structure itself), but now
that you mention it... maybe hipfw_init_context() could still be split
into two functions such that you can just hand it a fake ipq_packet pointer.
What do you think, René?

This would just postpone a more general problem of course, but maybe I
can look into it more thoroughly when the lectures are over.

6101. By René Hummen

revert re-ordering of includes

6102. By René Hummen

fix cyclic redundancy in midauth.h and firewall_defines.h

Revision history for this message
René Hummen (rene-hummen) wrote :

Begin forwarded message:
> From: René Hummen <email address hidden>
> Date: 2. November 2011 17:57:02 MEZ
> To: <email address hidden>
> Subject: Re: [hipl-dev] Re: [Merge] lp:~midauth-pisa-devs/hipl/midauth-firewall into lp:hipl
>
> On 25.10.2011, at 23:15, Christof Mroz wrote:
>> On 25.10.2011 16:35, René Hummen wrote:
>>>>>>> + if (!found) {
>>>>>>> + HIP_ERROR("CHALLENGE_RESPONSE found, but no matching nonce\n");
>>>>>>> + return ignore_missing_challenge_response ? 1 : 0;
>>>>>>> + }
>>>>>>> +
>>>>>>> + return found ? 1 : 0;
>>>>>>
>>>>>> You just checked found, no need to do it again.
>>>>>
>>>>> I guess that this has been done to ensure correct type conversion from
>>>>> bool to int.
>>>>
>>>> Read the code again, it's nonsense, "found" is initialized once and
>>>> never set again.
>>>
>>> You're right. I removed it and changed it to
>>>
>>>>>>> return ignore_missing_challenge_response ? 1 : 0;
>>
>> This doesn't look correct... you signal failure even though the CHALLENGE_RESPONSE was found? I think Diego meant to simply write
>>
>> return 1;
>>
>> Because we know that found is true at this point.
>
> found was always false before I removed the variable. Hence, !found evaluates to true. As this would be the path that the original code would follow, I decided to mimic it. Furthermore, if a correct response is found the while loop returns to the caller.

Revision history for this message
René Hummen (rene-hummen) wrote :

Begin forwarded message:
> From: René Hummen <email address hidden>
> Date: 2. November 2011 18:44:49 MEZ
> To: <email address hidden>
> Subject: Re: [hipl-dev] Re: [Merge] lp:~midauth-pisa-devs/hipl/midauth-firewall into lp:hipl
>
> On 27.10.2011, at 00:50, Christof Mroz wrote:
>> On 27.10.2011 00:20, Diego Biurrun wrote:
>>>> See the referenced thread for details, but essentially we need to
>>>> mock ipq_get_packet() which is usually provided by linking -lipq.
>>>
>>> What I don't get is the reason why we need to mock that function
>>> in the first place. Probably I am missing something totally
>>> obvious.
>>
>> Looking at the patch and judging from my memory, I think it's called by hipfw_init_context().
>> On the one hand, much of the firewall code makes heavy direct use of ipq structures (they're even part of the context structure itself), but now that you mention it... maybe hipfw_init_context() could still be split into two functions such that you can just hand it a fake ipq_packet pointer.
>> What do you think, René?
>
> I already thought about splitting up the code when implementing the unit test. But then I realized that mocking of the ipq functionality actually worked and decided to keep hip_fw_init_context() as it is. It's no problem to split up functionality though. Just one thing: Does anybody have a simple way to convert HIP_HEXDUMP output to char values like "\x00\x30\xF9\x16\x00\x88\xFF\xFF\x00". Last time I did that manually and realized that this was a bad idea. It would be perfect if we could specify the line length of the converted output in order to prevent long lines. If we have such a script, it's definitely worth adding it to our repository.
>
>> This would just postpone a more general problem of course, but maybe I can look into it more thoroughly when the lectures are over.
>
> Thanks, that would be great.

Revision history for this message
René Hummen (rene-hummen) wrote :

On 25.10.2011, at 23:04, Diego Biurrun wrote:
> On Tue, Oct 25, 2011 at 02:35:31PM +0000, René Hummen wrote:
>> On 25.10.2011, at 15:24, Diego Biurrun wrote:
>>> On Tue, Oct 25, 2011 at 02:28:06PM +0200, René Hummen wrote:
>>>> On 20.10.2011, at 14:15, Diego Biurrun wrote:
>>>>> On Wed, Oct 19, 2011 at 01:17:30PM +0000, René Hummen wrote:
>
>>>>>> - if (!hip_fw_verify_packet(common, tuple)) {
>>>>>> + if (!hipfw_midauth_verify_challenge(ctx, other_dir->midauth_nonce)) {
>>>>>> + HIP_ERROR("failed to verify midauth challenge\n");
>>>>>> + return 0;
>>>>>> + }
>>>>>
>>>>> 0 is returned in case of error?
>>>>
>>>> Yes, firewall/conntrack.c does not use the same semantics for return
>>>> values compared to the rest of the code.
>>>
>>> Then fix conntrack.c and don't make the code consistently inconsistent,
>>> cf. the boyscout rule.
>>
>> This would further increase the (already huge) merge request. It's
>> definitely out of focus of this branch.
>
> Nobody claims it has to be done as part of this merge request; it's
> easy enough to fix separately. If you are worried about the size of
> this merge request, that's all the more reason not to make unrelated
> changes to conntrack.c.

I still changed the return values of hip_fw_verify_and_store_host_id() because some calling functions actually expect non-zero values in case of an error. So I either need to change the caller or the callee. I'll directly apply this change to trunk though.

--
Dipl.-Inform. Rene Hummen, Ph.D. Student
Chair of Communication and Distributed Systems
RWTH Aachen University, Germany
tel: +49 241 80 20772
web: http://www.comsys.rwth-aachen.de/team/rene-hummen/

Revision history for this message
Christof Mroz (christof-mroz) wrote :

On 02.11.2011 18:44, René Hummen wrote:
> Just one thing: Does anybody have a simple way to convert HIP_HEXDUMP
> output to char values like "\x00\x30\xF9\x16\x00\x88\xFF\xFF\x00".
> Last time I did that manually and realized that this was a bad idea.
> It would be perfect if we could specify the line length of the
> converted output in order to prevent long lines. If we have such a
> script, it's definitely worth adding it to our repository.

It would probably be simpler if HIP_HEXDUMP could read e.g. an
environment variable which specifies the desired output format. Since it
affects the, debug build only it doesn't need to be documented to the
end user and such.

6103. By René Hummen

do not change return values of hip_fw_verify_packet()

6104. By René Hummen

split up hip_fw_init_context() for unit tests

Revision history for this message
René Hummen (rene-hummen) wrote :
Download full text (3.8 KiB)

On 27.10.2011, at 00:53, Diego Biurrun wrote:
> On Wed, Oct 26, 2011 at 11:16:18PM +0200, Christof Mroz wrote:
>> On 26.10.2011 22:57, Diego Biurrun wrote:
>>> On Tue, Oct 25, 2011 at 11:43:43PM +0200, Christof Mroz wrote:
>>>> On 25.10.2011 23:02, Diego Biurrun wrote:
>>>>> On Tue, Oct 25, 2011 at 02:35:31PM +0000, René Hummen wrote:
>>>>>> On 25.10.2011, at 15:24, Diego Biurrun wrote:
>>>>>>> On Tue, Oct 25, 2011 at 02:28:06PM +0200, René Hummen wrote:
>>>>>>>> On 20.10.2011, at 14:15, Diego Biurrun wrote:
>>>>>>>>> On Wed, Oct 19, 2011 at 01:17:30PM +0000, René Hummen wrote:
>>>>>>>>>
>>>>>>>>>> --- Makefile.am 2011-10-17 18:14:10 +0000
>>>>>>>>>> +++ Makefile.am 2011-10-19 13:13:48 +0000
>>>>>>>>>> @@ -253,7 +256,7 @@
>>>>>>>>>>
>>>>>>>>>> -test_check_firewall_LDFLAGS = -ldl
>>>>>>>>>> +test_check_firewall_LDFLAGS = -ldl -z muldefs
>>>>>>>>>
>>>>>>>>> We have solved this differently elsewhere by #including the .c file to
>>>>>>>>> unit-test static functions.
>>>>>>>>
>>>>>>>> This has been discussed previously on the list:
>>>>>>>> http://www.freelists.org/post/hipl-dev/Mock-functions-for-hipl-unit-tests
>>>>>>>
>>>>>>> But we currently don't favor that solution. If that needs changing,
>>>>>>> it's a topic for a separate merge request and would need to be changed
>>>>>>> in all places.
>>>>>>
>>>>>> The change was necessary in order to comply with our unit-test for new
>>>>>> code policy as unit-tests would otherwise not link correctly. The only
>>>>>> other option I see right now is to merge the code without unit-tests.
>>>>>
>>>>> No, the change is not necessary. As I said before, we have solved
>>>>> this differently elsewhere by #including the .c file to unit-test
>>>>> static functions.
>>>>
>>>> Including the .c file allows you to access static identifiers in
>>>> unit tests, but the libipq problem (see referenced thread) is a
>>>> different one.
>>>> Apparently, Hendrik already tried to mimic the other (working) tests
>>>> already without success.
>>>
>>> I'd like to know what is failing exactly and how before making
>>> a judgement here.
>>
>> See the referenced thread for details, but essentially we need to
>> mock ipq_get_packet() which is usually provided by linking -lipq.
>
> What I don't get is the reason why we need to mock that function
> in the first place. Probably I am missing something totally
> obvious.

We are calling fw_init_context() to derive a firewall context structure of an inbound HIP packet for unit-tests of midauth and rewrite functionality. fw_init_context() in turn calls ipq_get_packet(). The linker will complain about multiple definitions of ipq_get_packet() when compiling the unit tests with mocking of ipq_get_packet(). While this has not been a problem for other library functions so far, libipq behaves differently for some reason.

Anyway, I tried splitting up fw_init_context() into one function that calls ipq_get_packet() and another function that implements the setup of the firewall context struct - fw_setup_context(). This fixes the need for mocking ipq_get_packet(), so there should be no need for -z muldefs in the Makefile any more. However, now I am running ...

Read more...

Revision history for this message
Diego Biurrun (diego-biurrun) wrote :
Download full text (3.9 KiB)

On Tue, Nov 08, 2011 at 06:49:23PM +0000, René Hummen wrote:
> On 27.10.2011, at 00:53, Diego Biurrun wrote:
> > On Wed, Oct 26, 2011 at 11:16:18PM +0200, Christof Mroz wrote:
> >> On 26.10.2011 22:57, Diego Biurrun wrote:
> >>> On Tue, Oct 25, 2011 at 11:43:43PM +0200, Christof Mroz wrote:
> >>>> On 25.10.2011 23:02, Diego Biurrun wrote:
> >>>>> On Tue, Oct 25, 2011 at 02:35:31PM +0000, René Hummen wrote:
> >>>>>> On 25.10.2011, at 15:24, Diego Biurrun wrote:
> >>>>>>> On Tue, Oct 25, 2011 at 02:28:06PM +0200, René Hummen wrote:
> >>>>>>>> On 20.10.2011, at 14:15, Diego Biurrun wrote:
> >>>>>>>>> On Wed, Oct 19, 2011 at 01:17:30PM +0000, René Hummen wrote:
> >>>>>>>>>
> >>>>>>>>>> --- Makefile.am 2011-10-17 18:14:10 +0000
> >>>>>>>>>> +++ Makefile.am 2011-10-19 13:13:48 +0000
> >>>>>>>>>> @@ -253,7 +256,7 @@
> >>>>>>>>>>
> >>>>>>>>>> -test_check_firewall_LDFLAGS = -ldl
> >>>>>>>>>> +test_check_firewall_LDFLAGS = -ldl -z muldefs
> >>>>>>>>>
> >>>>>>>>> We have solved this differently elsewhere by #including the .c file to
> >>>>>>>>> unit-test static functions.
> >>>>>>>>
> >>>>>>>> This has been discussed previously on the list:
> >>>>>>>> http://www.freelists.org/post/hipl-dev/Mock-functions-for-hipl-unit-tests
> >>>>>>>
> >>>>>>> But we currently don't favor that solution. If that needs changing,
> >>>>>>> it's a topic for a separate merge request and would need to be changed
> >>>>>>> in all places.
> >>>>>>
> >>>>>> The change was necessary in order to comply with our unit-test for new
> >>>>>> code policy as unit-tests would otherwise not link correctly. The only
> >>>>>> other option I see right now is to merge the code without unit-tests.
> >>>>>
> >>>>> No, the change is not necessary. As I said before, we have solved
> >>>>> this differently elsewhere by #including the .c file to unit-test
> >>>>> static functions.
> >>>>
> >>>> Including the .c file allows you to access static identifiers in
> >>>> unit tests, but the libipq problem (see referenced thread) is a
> >>>> different one.
> >>>> Apparently, Hendrik already tried to mimic the other (working) tests
> >>>> already without success.
> >>>
> >>> I'd like to know what is failing exactly and how before making
> >>> a judgement here.
> >>
> >> See the referenced thread for details, but essentially we need to
> >> mock ipq_get_packet() which is usually provided by linking -lipq.
> >
> > What I don't get is the reason why we need to mock that function
> > in the first place. Probably I am missing something totally
> > obvious.
>
> We are calling fw_init_context() to derive a firewall context
> structure of an inbound HIP packet for unit-tests of midauth
> and rewrite functionality. fw_init_context() in turn calls
> ipq_get_packet(). The linker will complain about multiple definitions
> of ipq_get_packet() when compiling the unit tests with mocking of
> ipq_get_packet(). While this has not been a problem for other library
> functions so far, libipq behaves differently for some reason.
>
> Anyway, I tried splitting up fw_init_context() into one function that
> calls ipq_get_packet() and another function that implements the setup
> of the firew...

Read more...

6105. By Henrik Ziegeldorf

-z muldefs is necessary with mock tests

6106. By Henrik Ziegeldorf

Reversed revision 6104. The split is unnecessary if mocking still used.

6107. By Henrik Ziegeldorf

Merged trunk.

Revision history for this message
Miika Komu (miika-iki) wrote :
Download full text (3.6 KiB)

Hi,

On 08/11/11 20:49, René Hummen wrote:
> On 27.10.2011, at 00:53, Diego Biurrun wrote:
>> On Wed, Oct 26, 2011 at 11:16:18PM +0200, Christof Mroz wrote:
>>> On 26.10.2011 22:57, Diego Biurrun wrote:
>>>> On Tue, Oct 25, 2011 at 11:43:43PM +0200, Christof Mroz wrote:
>>>>> On 25.10.2011 23:02, Diego Biurrun wrote:
>>>>>> On Tue, Oct 25, 2011 at 02:35:31PM +0000, René Hummen wrote:
>>>>>>> On 25.10.2011, at 15:24, Diego Biurrun wrote:
>>>>>>>> On Tue, Oct 25, 2011 at 02:28:06PM +0200, René Hummen wrote:
>>>>>>>>> On 20.10.2011, at 14:15, Diego Biurrun wrote:
>>>>>>>>>> On Wed, Oct 19, 2011 at 01:17:30PM +0000, René Hummen wrote:
>>>>>>>>>>
>>>>>>>>>>> --- Makefile.am 2011-10-17 18:14:10 +0000
>>>>>>>>>>> +++ Makefile.am 2011-10-19 13:13:48 +0000
>>>>>>>>>>> @@ -253,7 +256,7 @@
>>>>>>>>>>>
>>>>>>>>>>> -test_check_firewall_LDFLAGS = -ldl
>>>>>>>>>>> +test_check_firewall_LDFLAGS = -ldl -z muldefs
>>>>>>>>>>
>>>>>>>>>> We have solved this differently elsewhere by #including the .c file to
>>>>>>>>>> unit-test static functions.
>>>>>>>>>
>>>>>>>>> This has been discussed previously on the list:
>>>>>>>>> http://www.freelists.org/post/hipl-dev/Mock-functions-for-hipl-unit-tests
>>>>>>>>
>>>>>>>> But we currently don't favor that solution. If that needs changing,
>>>>>>>> it's a topic for a separate merge request and would need to be changed
>>>>>>>> in all places.
>>>>>>>
>>>>>>> The change was necessary in order to comply with our unit-test for new
>>>>>>> code policy as unit-tests would otherwise not link correctly. The only
>>>>>>> other option I see right now is to merge the code without unit-tests.
>>>>>>
>>>>>> No, the change is not necessary. As I said before, we have solved
>>>>>> this differently elsewhere by #including the .c file to unit-test
>>>>>> static functions.
>>>>>
>>>>> Including the .c file allows you to access static identifiers in
>>>>> unit tests, but the libipq problem (see referenced thread) is a
>>>>> different one.
>>>>> Apparently, Hendrik already tried to mimic the other (working) tests
>>>>> already without success.
>>>>
>>>> I'd like to know what is failing exactly and how before making
>>>> a judgement here.
>>>
>>> See the referenced thread for details, but essentially we need to
>>> mock ipq_get_packet() which is usually provided by linking -lipq.
>>
>> What I don't get is the reason why we need to mock that function
>> in the first place. Probably I am missing something totally
>> obvious.
>
> We are calling fw_init_context() to derive a firewall context structure of an inbound HIP packet for unit-tests of midauth and rewrite functionality. fw_init_context() in turn calls ipq_get_packet(). The linker will complain about multiple definitions of ipq_get_packet() when compiling the unit tests with mocking of ipq_get_packet(). While this has not been a problem for other library functions so far, libipq behaves differently for some reason.
>
> Anyway, I tried splitting up fw_init_context() into one function that calls ipq_get_packet() and another function that implements the setup of the firewall context struct - fw_setup_context(). This fixes the need for mocking ipq_get_packet(), so t...

Read more...

Revision history for this message
Miika Komu (miika-iki) wrote :
Download full text (3.9 KiB)

Hi,

On 12/11/11 00:09, Miika Komu wrote:
> Hi,
>
> On 08/11/11 20:49, René Hummen wrote:
>> On 27.10.2011, at 00:53, Diego Biurrun wrote:
>>> On Wed, Oct 26, 2011 at 11:16:18PM +0200, Christof Mroz wrote:
>>>> On 26.10.2011 22:57, Diego Biurrun wrote:
>>>>> On Tue, Oct 25, 2011 at 11:43:43PM +0200, Christof Mroz wrote:
>>>>>> On 25.10.2011 23:02, Diego Biurrun wrote:
>>>>>>> On Tue, Oct 25, 2011 at 02:35:31PM +0000, René Hummen wrote:
>>>>>>>> On 25.10.2011, at 15:24, Diego Biurrun wrote:
>>>>>>>>> On Tue, Oct 25, 2011 at 02:28:06PM +0200, René Hummen wrote:
>>>>>>>>>> On 20.10.2011, at 14:15, Diego Biurrun wrote:
>>>>>>>>>>> On Wed, Oct 19, 2011 at 01:17:30PM +0000, René Hummen wrote:
>>>>>>>>>>>
>>>>>>>>>>>> --- Makefile.am 2011-10-17 18:14:10 +0000
>>>>>>>>>>>> +++ Makefile.am 2011-10-19 13:13:48 +0000
>>>>>>>>>>>> @@ -253,7 +256,7 @@
>>>>>>>>>>>>
>>>>>>>>>>>> -test_check_firewall_LDFLAGS = -ldl
>>>>>>>>>>>> +test_check_firewall_LDFLAGS = -ldl -z muldefs
>>>>>>>>>>>
>>>>>>>>>>> We have solved this differently elsewhere by #including the
>>>>>>>>>>> .c file to
>>>>>>>>>>> unit-test static functions.
>>>>>>>>>>
>>>>>>>>>> This has been discussed previously on the list:
>>>>>>>>>> http://www.freelists.org/post/hipl-dev/Mock-functions-for-hipl-unit-tests
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> But we currently don't favor that solution. If that needs
>>>>>>>>> changing,
>>>>>>>>> it's a topic for a separate merge request and would need to be
>>>>>>>>> changed
>>>>>>>>> in all places.
>>>>>>>>
>>>>>>>> The change was necessary in order to comply with our unit-test
>>>>>>>> for new
>>>>>>>> code policy as unit-tests would otherwise not link correctly.
>>>>>>>> The only
>>>>>>>> other option I see right now is to merge the code without
>>>>>>>> unit-tests.
>>>>>>>
>>>>>>> No, the change is not necessary. As I said before, we have solved
>>>>>>> this differently elsewhere by #including the .c file to unit-test
>>>>>>> static functions.
>>>>>>
>>>>>> Including the .c file allows you to access static identifiers in
>>>>>> unit tests, but the libipq problem (see referenced thread) is a
>>>>>> different one.
>>>>>> Apparently, Hendrik already tried to mimic the other (working) tests
>>>>>> already without success.
>>>>>
>>>>> I'd like to know what is failing exactly and how before making
>>>>> a judgement here.
>>>>
>>>> See the referenced thread for details, but essentially we need to
>>>> mock ipq_get_packet() which is usually provided by linking -lipq.
>>>
>>> What I don't get is the reason why we need to mock that function
>>> in the first place. Probably I am missing something totally
>>> obvious.
>>
>> We are calling fw_init_context() to derive a firewall context
>> structure of an inbound HIP packet for unit-tests of midauth and
>> rewrite functionality. fw_init_context() in turn calls
>> ipq_get_packet(). The linker will complain about multiple definitions
>> of ipq_get_packet() when compiling the unit tests with mocking of
>> ipq_get_packet(). While this has not been a problem for other library
>> functions so far, libipq behaves differently for some reason.
>>
>> Anyway, I tried splitting up fw_init_context() into one function that
>> calls ipq_get_...

Read more...

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Makefile.am'
2--- Makefile.am 2011-10-17 18:14:10 +0000
3+++ Makefile.am 2011-10-25 12:58:23 +0000
4@@ -153,6 +153,7 @@
5 firewall/lsi.c \
6 firewall/port_bindings.c \
7 firewall/reinject.c \
8+ firewall/rewrite.c \
9 firewall/rule_management.c \
10 firewall/user_ipsec_api.c \
11 firewall/user_ipsec_esp.c \
12@@ -161,8 +162,7 @@
13 modules/midauth/lib/midauth_builder.c
14
15 if HIP_MIDAUTH
16-firewall_hipfw_sources += firewall/midauth.c \
17- firewall/pisa.c \
18+firewall_hipfw_sources += firewall/pisa.c \
19 firewall/pisa_cert.c
20 endif
21
22@@ -171,6 +171,7 @@
23 # Add all files that need to be excluded here.
24 firewall_hipfw_SOURCES = $(firewall_hipfw_sources) \
25 firewall/conntrack.c \
26+ firewall/midauth.c \
27 firewall/main.c
28
29 lib_core_libhipcore_la_SOURCES = lib/core/builder.c \
30@@ -215,7 +216,9 @@
31 test/firewall/file_buffer.c \
32 test/firewall/helpers.c \
33 test/firewall/line_parser.c \
34+ test/firewall/midauth.c \
35 test/firewall/port_bindings.c \
36+ test/firewall/rewrite.c \
37 $(firewall_hipfw_sources)
38
39 test_check_lib_core_SOURCES = test/check_lib_core.c \
40@@ -253,7 +256,7 @@
41
42 ### dynamic library dependencies ###
43
44-test_check_firewall_LDFLAGS = -ldl
45+test_check_firewall_LDFLAGS = -ldl -z muldefs
46
47 dist_sbin_SCRIPTS = tools/hipdnskeyparse/hipdnskeyparse \
48 tools/hipdnsproxy/hipdnsproxy \
49
50=== modified file 'firewall/conntrack.c'
51--- firewall/conntrack.c 2011-10-19 09:51:41 +0000
52+++ firewall/conntrack.c 2011-10-25 12:58:23 +0000
53@@ -998,7 +998,7 @@
54 *
55 * @param common the hip packet to be verified
56 * @param tuple the corresponding connection tuple
57- * @return 1 for valid packets, 0 otherwise
58+ * @return 0 for valid packets, 1 otherwise
59 */
60 static int hip_fw_verify_packet(struct hip_common *const common,
61 const struct tuple *const tuple)
62@@ -1017,12 +1017,12 @@
63 common)) {
64 HIP_INFO("Signature verification failed\n");
65
66- return 0;
67+ return 1;
68 }
69
70 HIP_INFO("Signature successfully verified\n");
71
72- return 1;
73+ return 0;
74 }
75
76 /** Verify message authenticity for message types without existing security
77@@ -1030,7 +1030,9 @@
78 *
79 * @param common the hip packet to be verified
80 * @param tuple the corresponding connection tuple
81- * @return 1 for valid packets, 0 otherwise
82+ * @return 0 for valid packets,
83+ * 1 if HOST_ID missing or verification unsuccessful, and
84+ * -1 in case of an error
85 */
86 static int hip_fw_verify_and_store_host_id(struct hip_common *const common,
87 struct tuple *const tuple)
88@@ -1040,6 +1042,11 @@
89 hip_tlv_len len = 0;
90 int err = 0;
91
92+ HIP_ASSERT(common != NULL);
93+ HIP_ASSERT(tuple != NULL);
94+ HIP_ASSERT(tuple->hip_tuple != NULL);
95+ HIP_ASSERT(tuple->hip_tuple->data != NULL);
96+
97 HIP_IFEL(!host_id, -1, "Awaiting HOST_ID in control message, but none found\n");
98
99 len = hip_get_param_total_len(host_id);
100@@ -1077,7 +1084,7 @@
101 goto out_err;
102 }
103
104- err = !hip_fw_verify_packet(common, tuple);
105+ err = hip_fw_verify_packet(common, tuple);
106
107 out_err:
108 if (err) {
109@@ -1170,7 +1177,7 @@
110 */
111 static int handle_r1(struct hip_common *const common,
112 struct tuple *const tuple,
113- UNUSED struct hip_fw_context *const ctx)
114+ struct hip_fw_context *const ctx)
115 {
116 if (hip_fw_verify_and_store_host_id(common, tuple)) {
117 HIP_ERROR("unable to create security state from R1 packet\n");
118@@ -1183,6 +1190,11 @@
119 return 0;
120 }
121
122+ if (!hipfw_midauth_add_challenge(ctx, tuple->midauth_nonce)) {
123+ HIP_ERROR("failed to add midauth challenge\n");
124+ return 0;
125+ }
126+
127 tuple->connection->state = HIP_STATE_R1_SENT;
128 return 1;
129 }
130@@ -1203,7 +1215,19 @@
131 struct tuple *const tuple,
132 struct hip_fw_context *const ctx)
133 {
134- const struct hip_esp_info *const esp_info = hip_get_param(common, HIP_PARAM_ESP_INFO);
135+ struct tuple *other_dir = NULL;
136+ const struct hip_esp_info *const esp_info = hip_get_param(common, HIP_PARAM_ESP_INFO);
137+
138+ if (tuple->direction == ORIGINAL_DIR) {
139+ other_dir = &tuple->connection->reply;
140+ } else {
141+ other_dir = &tuple->connection->original;
142+ }
143+
144+ if (!hipfw_midauth_verify_challenge(ctx, other_dir->midauth_nonce)) {
145+ HIP_ERROR("failed to verify midauth challenge\n");
146+ return 0;
147+ }
148
149 if (hip_fw_verify_and_store_host_id(common, tuple)) {
150 HIP_ERROR("unable to create security state from I2 packet\n");
151@@ -1221,6 +1245,11 @@
152 return 0;
153 }
154
155+ if (!hipfw_midauth_add_challenge(ctx, tuple->midauth_nonce)) {
156+ HIP_ERROR("failed to add midauth challenge\n");
157+ return 0;
158+ }
159+
160 tuple->connection->state = HIP_STATE_I2_SENT;
161 return 1;
162 }
163@@ -1242,9 +1271,21 @@
164 struct tuple *const tuple,
165 const struct hip_fw_context *const ctx)
166 {
167- const struct hip_esp_info *const esp_info = hip_get_param(common, HIP_PARAM_ESP_INFO);
168-
169- if (!hip_fw_verify_packet(common, tuple)) {
170+ const struct tuple *other_dir = NULL;
171+ const struct hip_esp_info *const esp_info = hip_get_param(common, HIP_PARAM_ESP_INFO);
172+
173+ if (tuple->direction == ORIGINAL_DIR) {
174+ other_dir = &tuple->connection->reply;
175+ } else {
176+ other_dir = &tuple->connection->original;
177+ }
178+
179+ if (!hipfw_midauth_verify_challenge(ctx, other_dir->midauth_nonce)) {
180+ HIP_ERROR("failed to verify midauth challenge\n");
181+ return 0;
182+ }
183+
184+ if (hip_fw_verify_packet(common, tuple)) {
185 HIP_ERROR("failed to verify R2 packet\n");
186 return 0;
187 }
188@@ -1421,9 +1462,6 @@
189
190 remove_connection(tuple->connection);
191
192- /** FIXME the firewall should not care about locator for esp tracking
193- *
194- * NOTE: modify this regardingly! */
195 if (insert_connection_from_update(common, ctx, esp_info)) {
196 HIP_ERROR("connection insertion failed\n");
197
198@@ -1502,11 +1540,12 @@
199 struct tuple *tuple,
200 struct hip_fw_context *const ctx)
201 {
202- const struct hip_esp_info *esp_info = NULL;
203- const struct hip_locator *locator = NULL;
204- const struct hip_seq *seq = NULL;
205- const struct hip_ack *ack = NULL;
206- enum hip_state state = HIP_STATE_NONE;
207+ const struct hip_esp_info *esp_info = NULL;
208+ const struct hip_locator *locator = NULL;
209+ const struct hip_seq *seq = NULL;
210+ const struct hip_ack *ack = NULL;
211+ struct tuple *other_dir = NULL;
212+ enum hip_state state = HIP_STATE_NONE;
213
214 /* classify UPDATE message */
215 esp_info = hip_get_param(common, HIP_PARAM_ESP_INFO);
216@@ -1526,14 +1565,26 @@
217 tuple = get_tuple_by_hits(&common->hits, &common->hitr);
218 }
219
220+ if (!tuple || !hipfw_midauth_add_challenge(ctx, tuple->midauth_nonce)) {
221+ HIP_ERROR("failed to add midauth challenge\n");
222+ return 0;
223+ }
224+
225 state = HIP_STATE_U1_SENT;
226 } else if (esp_info && seq && ack) {
227 if (!tuple) {
228 HIP_ERROR("Insufficient stored state to process UPDATE\n");
229 return 0;
230 }
231-
232- if (!hip_fw_verify_packet(common, tuple)) {
233+ other_dir = tuple->direction == ORIGINAL_DIR ? &tuple->connection->reply
234+ : &tuple->connection->original;
235+
236+ if (!hipfw_midauth_verify_challenge(ctx, other_dir->midauth_nonce)) {
237+ HIP_ERROR("failed to verify midauth challenge\n");
238+ return 0;
239+ }
240+
241+ if (hip_fw_verify_and_store_host_id(common, tuple)) {
242 HIP_ERROR("failed to verify UPDATE packet\n");
243 return 0;
244 }
245@@ -1543,14 +1594,27 @@
246 return 0;
247 }
248
249+ if (!tuple || !hipfw_midauth_add_challenge(ctx, tuple->midauth_nonce)) {
250+ HIP_ERROR("failed to add midauth challenge\n");
251+ return 0;
252+ }
253+
254 state = HIP_STATE_U2_SENT;
255 } else if (ack) {
256 if (!tuple) {
257 HIP_ERROR("Insufficient stored state to process UPDATE\n");
258 return 0;
259 }
260-
261- if (!hip_fw_verify_packet(common, tuple)) {
262+ other_dir = tuple->direction == ORIGINAL_DIR ? &tuple->connection->reply
263+ : &tuple->connection->original;
264+
265+ if (!other_dir ||
266+ !hipfw_midauth_verify_challenge(ctx, other_dir->midauth_nonce)) {
267+ HIP_ERROR("failed to verify midauth challenge\n");
268+ return 0;
269+ }
270+
271+ if (hip_fw_verify_and_store_host_id(common, tuple)) {
272 HIP_ERROR("failed to verify UPDATE packet\n");
273 return 0;
274 }
275@@ -1592,7 +1656,7 @@
276 #endif
277 HIP_IFEL(!tuple, 1, "no connection state for CLOSE\n");
278
279- HIP_IFEL(!hip_fw_verify_packet(common, tuple), 0,
280+ HIP_IFEL(hip_fw_verify_packet(common, tuple), 0,
281 "failed to verify CLOSE packet\n");
282
283 tuple->connection->state = HIP_STATE_CLOSING;
284@@ -1628,7 +1692,7 @@
285 #endif
286 HIP_IFEL(!tuple, 1, "no connection state for CLOSE_ACK\n");
287
288- HIP_IFEL(!hip_fw_verify_packet(common, tuple), 0,
289+ HIP_IFEL(hip_fw_verify_packet(common, tuple), 0,
290 "failed to verify CLOSE_ACK packet\n");
291
292 remove_connection(tuple->connection);
293
294=== modified file 'firewall/firewall.c'
295--- firewall/firewall.c 2011-08-16 07:49:25 +0000
296+++ firewall/firewall.c 2011-10-25 12:58:23 +0000
297@@ -76,12 +76,13 @@
298 #include "lib/core/prefix.h"
299 #include "lib/core/util.h"
300 #include "hipd/hipd.h"
301-#include "config.h"
302 #include "cache.h"
303 #include "common_types.h"
304+#include "config.h"
305 #include "conntrack.h"
306 #include "esp_prot_api.h"
307 #include "esp_prot_conntrack.h"
308+#include "firewall.h"
309 #include "firewall_control.h"
310 #include "firewall_defines.h"
311 #include "helpers.h"
312@@ -90,9 +91,9 @@
313 #include "pisa.h"
314 #include "port_bindings.h"
315 #include "reinject.h"
316+#include "rewrite.h"
317 #include "rule_management.h"
318 #include "user_ipsec_api.h"
319-#include "firewall.h"
320
321
322 /* location of the lock file */
323@@ -134,9 +135,6 @@
324 int esp_relay = 0;
325 int hip_esp_protection = 0;
326 int esp_speedup = 0; /**< Enable esp speedup via dynamic iptables usage (-u option). */
327-#ifdef CONFIG_HIP_MIDAUTH
328-int use_midauth = 0;
329-#endif
330
331 /** Use this to send and receive responses to hipd. Notice that
332 * firewall_control.c has a separate socket for receiving asynchronous
333@@ -485,9 +483,7 @@
334 HIP_IFEL(hip_fw_init_esp_prot(), -1, "failed to load extension\n");
335 HIP_IFEL(hip_fw_init_esp_prot_conntrack(), -1, "failed to load extension\n");
336
337-#ifdef CONFIG_HIP_MIDAUTH
338 midauth_init();
339-#endif
340
341 // Initializing local port cache database
342 hip_port_bindings_init(true);
343@@ -1147,13 +1143,6 @@
344 {
345 HIP_DEBUG("\n");
346
347-#ifdef CONFIG_HIP_MIDAUTH
348- if (use_midauth) {
349- if (midauth_filter_hip(ctx) == NF_DROP) {
350- return NF_DROP;
351- }
352- }
353-#endif
354 // for now forward and output are handled symmetrically
355 return hip_fw_handle_hip_output(ctx);
356 }
357@@ -1530,22 +1519,6 @@
358 }
359
360 /**
361- * Set an accept verdict for a modified packet
362- *
363- * @param handle ipqueue file handle
364- * @param packet_id ipqueue packet id
365- * @param len length of buf
366- * @param buf the packet to be accepted
367- *
368- */
369-static void allow_modified_packet(struct ipq_handle *handle, unsigned long packet_id,
370- size_t len, unsigned char *buf)
371-{
372- ipq_set_verdict(handle, packet_id, NF_ACCEPT, len, buf);
373- HIP_DEBUG("Packet accepted with modifications\n\n");
374-}
375-
376-/**
377 * Allow a packet to pass
378 *
379 * @param handle the handle for the packets.
380@@ -1639,9 +1612,7 @@
381 allow_packet(hndl, ctx->ipq_packet->packet_id);
382 } else {
383 HIP_DEBUG("=== Verdict: allow modified packet ===\n");
384- allow_modified_packet(hndl, ctx->ipq_packet->packet_id,
385- ctx->ipq_packet->data_len,
386- ctx->ipq_packet->payload);
387+ allow_modified_packet(hndl, ctx);
388 }
389 } else {
390 HIP_DEBUG("=== Verdict: drop packet ===\n");
391@@ -1928,7 +1899,7 @@
392 continue;
393 }
394
395-#ifdef CONFIG_HIP_MIDAUTH
396+#ifdef CONFIG_HIP_PISA
397 if (use_midauth) {
398 pisa_check_for_random_update();
399 }
400
401=== modified file 'firewall/firewall.h'
402--- firewall/firewall.h 2011-04-05 16:44:22 +0000
403+++ firewall/firewall.h 2011-10-25 12:58:23 +0000
404@@ -43,7 +43,6 @@
405 extern int hip_lsi_support;
406 extern int esp_relay;
407 extern int hip_esp_protection;
408-extern int use_midauth;
409 extern int hip_fw_sock;
410 extern int system_based_opp_mode;
411 extern int esp_speedup;
412
413=== modified file 'firewall/firewall_defines.h'
414--- firewall/firewall_defines.h 2011-09-07 13:33:42 +0000
415+++ firewall/firewall_defines.h 2011-10-25 12:58:23 +0000
416@@ -50,6 +50,12 @@
417 FW_PROTO_NUM
418 };
419
420+/**
421+ * @note When adding new members, check if hip_fw_context_enable_write() needs
422+ * to be updated as well.
423+ * @see hip_fw_context_enable_write()
424+ * @see hip_fw_context_enable_write_inplace()
425+ */
426 struct hip_fw_context {
427 // queued packet
428 ipq_packet_msg_t *ipq_packet;
429@@ -74,6 +80,8 @@
430 int modified;
431 };
432
433+#include "midauth.h"
434+
435 /********** State table structures **************/
436
437 struct esp_address {
438@@ -137,6 +145,7 @@
439 int esp_relay;
440 struct in6_addr esp_relay_daddr;
441 in_port_t esp_relay_dport;
442+ uint8_t midauth_nonce[MIDAUTH_DEFAULT_NONCE_LENGTH];
443 };
444
445 struct connection {
446@@ -150,9 +159,7 @@
447 /* members needed for ESP protection extension */
448 int num_esp_prot_tfms;
449 uint8_t esp_prot_tfms[MAX_NUM_TRANSFORMS];
450-#ifdef CONFIG_HIP_MIDAUTH
451- int pisa_state;
452-#endif
453+ int pisa_state;
454 };
455
456 #endif /* HIP_FIREWALL_FIREWALL_DEFINES_H */
457
458=== modified file 'firewall/main.c'
459--- firewall/main.c 2011-06-22 13:25:54 +0000
460+++ firewall/main.c 2011-10-25 12:58:23 +0000
461@@ -45,6 +45,7 @@
462 #include "lib/core/util.h"
463 #include "firewall.h"
464 #include "conntrack.h"
465+#include "midauth.h"
466
467
468 /**
469@@ -53,10 +54,7 @@
470 static void hipfw_usage(void)
471 {
472 puts("HIP Firewall");
473- puts("Usage: hipfw [-f file_name] [-d|-v] [-A] [-F] [-H] [-b] [-a] [-c] [-k] [-i|-I|-e] [-l] [-o] [-p] [-t <seconds>] [-u] [-h] [-V]");
474-#ifdef CONFIG_HIP_MIDAUTH
475- puts(" [-m]");
476-#endif
477+ puts("Usage: hipfw [-f file_name] [-d|-v] [-A] [-F] [-H] [-b] [-a] [-c] [-k] [-i|-I|-e] [-l] [-m] [-o] [-p] [-t <seconds>] [-u] [-h] [-V]");
478 puts("");
479 puts(" -f file_name = is a path to a file containing firewall filtering rules");
480 puts(" -V = print version information and exit");
481@@ -71,14 +69,11 @@
482 puts(" -I = as -i, also allow fallback to kernel ipsec when exiting hipfw");
483 puts(" -e = use esp protection extension (also sets -i)");
484 puts(" -l = activate lsi support");
485+ puts(" -m = middlebox authentication");
486 puts(" -p = run with lowered privileges. iptables rules will not be flushed on exit");
487 puts(" -t <seconds> = set timeout interval to <seconds>. Disable if <seconds> = 0");
488 puts(" -u = attempt to speed up esp traffic using iptables rules");
489 puts(" -h = print this help");
490-#ifdef CONFIG_HIP_MIDAUTH
491- puts(" -m = middlebox authentication");
492- puts(" -w = IP address of web-based authentication server");
493-#endif
494 puts("");
495 }
496
497@@ -153,11 +148,9 @@
498 hip_lsi_support = 1;
499 break;
500 case 'm':
501-#ifdef CONFIG_HIP_MIDAUTH
502 filter_traffic = 1;
503 use_midauth = 1;
504 break;
505-#endif
506 case 'p':
507 limit_capabilities = 1;
508 break;
509
510=== modified file 'firewall/midauth.c'
511--- firewall/midauth.c 2011-08-15 14:11:56 +0000
512+++ firewall/midauth.c 2011-10-25 12:58:23 +0000
513@@ -38,416 +38,245 @@
514
515 #define _BSD_SOURCE
516
517-#include <stdint.h>
518+#include <openssl/rand.h>
519+#include <stdbool.h>
520 #include <string.h>
521-#include <arpa/inet.h>
522-#include <netinet/ip.h>
523-#include <sys/socket.h>
524-#include <sys/types.h>
525-#include <linux/netfilter.h>
526
527 #include "lib/core/builder.h"
528 #include "lib/core/debug.h"
529-#include "lib/core/ife.h"
530-#include "lib/core/protodefs.h"
531 #include "lib/core/solve.h"
532-#include "lib/tool/checksum.h"
533+#include "modules/midauth/hipd/midauth.h"
534+#include "modules/midauth/lib/midauth_builder.h"
535 #include "firewall_defines.h"
536-#include "pisa.h"
537+#include "rewrite.h"
538 #include "midauth.h"
539
540
541-static struct midauth_handlers handlers;
542-
543-/**
544- * Changes IPv4 header to match new length and updates the checksum.
545- *
546- * @param ip a pointer to the IPv4 header
547- * @param len new payload length
548- */
549-static void update_ipv4_header(struct iphdr *ip, int len)
550-{
551- unsigned short *w = (unsigned short *) ip;
552- int hdrlen, checksum = 0;
553-
554- ip->tot_len = htons(len);
555- ip->check = 0;
556-
557- for (hdrlen = ip->ihl * 4, checksum = 0; hdrlen > 1; hdrlen -= 2) {
558- checksum += *w++;
559- }
560- if (hdrlen == 1) {
561- unsigned short padding = 0;
562- *(unsigned char *) (&padding) = *(unsigned char *) w;
563- checksum += padding;
564- }
565-
566- checksum = (checksum >> 16) + (checksum & 0xffff);
567- checksum += checksum >> 16;
568-
569- ip->check = ~checksum;
570-}
571-
572-/**
573- * Changes IPv6 header to match new length.
574- *
575- * @param ip a pointer to the IPv6 header
576- * @param len new IPv6 packet length
577- */
578-static void update_ipv6_header(struct ip6_hdr *ip, int len)
579-{
580- ip->ip6_ctlun.ip6_un1.ip6_un1_plen = htons(len - sizeof(struct ip6_hdr));
581-}
582-
583-#define CHECKSUM_CARRY(x) \
584- (x = (x >> 16) + (x & 0xffff), (~(x + (x >> 16)) & 0xffff))
585-
586-/**
587- * Changes UDP header for IPv4 to match new content and updates the checksum.
588- *
589- * @param ip a pointer to the IPv4 header, not the UDP header
590- * @param len total length of the IPv4 packet
591- */
592-static void update_udp_header(struct iphdr *ip, int len)
593-{
594- unsigned long sum;
595- uint16_t *w = (uint16_t *) ((unsigned char *) ip + (ip->ihl * 4));
596- uint16_t protocol = ntohs(IPPROTO_UDP);
597- int i;
598- struct udphdr *udp = (struct udphdr *) w;
599-
600- len -= ip->ihl * 4;
601-
602- udp->check = 0;
603- udp->len = htons(len);
604-
605- /* UDP header and data */
606- sum = 0;
607- while (len > 0) {
608- sum += *w++;
609- len -= 2;
610- }
611- if (len == 1) {
612- unsigned short padding = 0;
613- *(unsigned char *) (&padding) = *(unsigned char *) w;
614- sum += padding;
615- }
616-
617- /* add UDP pseudoheader */
618- w = (uint16_t *) &ip->saddr;
619- for (i = 0; i < 4; w++, i++) {
620- sum += *w;
621- }
622- sum += protocol;
623- sum += udp->len;
624-
625- /* set the checksum */
626- udp->check = CHECKSUM_CARRY(sum);
627-}
628-
629-/**
630- * Calculate the new checksum for the HIP packet in IPv4. Note that UDP
631- * encapsulated HIP packets don't have a checksum. Therefore don't call this
632- * function for them.
633- *
634- * @param ip the modified IP packet
635- */
636-static void update_hip_checksum_ipv4(struct iphdr *ip)
637-{
638- struct sockaddr_in src = { 0 }, dst = { 0 };
639- struct hip_common *msg = (struct hip_common *) ((char *) ip +
640- (ip->ihl * 4));
641-
642- src.sin_family = AF_INET;
643- memcpy(&src.sin_addr, &ip->saddr, sizeof(uint32_t));
644-
645- dst.sin_family = AF_INET;
646- memcpy(&dst.sin_addr, &ip->daddr, sizeof(uint32_t));
647-
648- hip_zero_msg_checksum(msg);
649- msg->checksum = hip_checksum_packet((char *) msg,
650- (struct sockaddr *) &src,
651- (struct sockaddr *) &dst);
652-}
653-
654-/**
655- * Calculate the new checksum for the HIP packet in IPv6.
656- *
657- * @param ip the modified IP packet
658- */
659-static void update_hip_checksum_ipv6(struct ip6_hdr *ip)
660-{
661- struct sockaddr_in6 src = { 0 }, dst = { 0 };
662- struct hip_common *msg = (struct hip_common *) ((char *) ip +
663- sizeof(struct ip6_hdr));
664-
665- src.sin6_family = AF_INET6;
666- memcpy(&src.sin6_addr, &ip->ip6_src, sizeof(struct in6_addr));
667-
668- dst.sin6_family = AF_INET6;
669- memcpy(&dst.sin6_addr, &ip->ip6_dst, sizeof(struct in6_addr));
670-
671- hip_zero_msg_checksum(msg);
672- msg->checksum = hip_checksum_packet((char *) msg,
673- (struct sockaddr *) &src,
674- (struct sockaddr *) &dst);
675-}
676-
677-/**
678- * Take care of adapting all headers in front of the HIP payload to the new
679- * content.
680- *
681- * @param ctx context of the modified midauth packet
682- */
683-static void midauth_update_all_headers(struct hip_fw_context *ctx)
684-{
685- struct iphdr *ipv4 = NULL;
686- struct ip6_hdr *ipv6 = NULL;
687- size_t len = 0;
688-
689- len = hip_get_msg_total_len(ctx->transport_hdr.hip);
690-
691- switch (ctx->ip_version) {
692- case 4:
693- ipv4 = (struct iphdr *) ctx->ipq_packet->payload;
694- len += ipv4->ihl * 4;
695- if (ipv4->protocol == IPPROTO_UDP) {
696- len += sizeof(struct udphdr) + HIP_UDP_ZERO_BYTES_LEN;
697- update_udp_header(ipv4, len);
698- } else {
699- update_hip_checksum_ipv4(ipv4);
700- }
701- update_ipv4_header(ipv4, len);
702- break;
703- case 6:
704- ipv6 = (struct ip6_hdr *) ctx->ipq_packet->payload;
705- len += sizeof(struct ip6_hdr);
706- update_hip_checksum_ipv6(ipv6);
707- update_ipv6_header(ipv6, len);
708- break;
709- default:
710- HIP_ERROR("Unknown IP version. %i, expected 4 or 6.\n",
711- ctx->ip_version);
712- break;
713- }
714-
715- ctx->ipq_packet->data_len = len;
716-}
717-
718-/**
719- * Verify that the challenge response in a packet is valid
720- *
721- * @param solution challenge response parameter
722- * @param initiator_hit HIT of the initiator
723- * @param responder_hit HIT of the receiver
724- * @return 0 on success, <0 otherwise
725- */
726-int midauth_verify_challenge_response(const struct hip_challenge_response *const solution,
727- const hip_hit_t initiator_hit,
728- const hip_hit_t responder_hit)
729-{
730- int err = 0;
731- struct puzzle_hash_input puzzle_input;
732- uint8_t digest[HIP_AH_SHA_LEN];
733-
734- HIP_IFEL(hip_build_digest(HIP_DIGEST_SHA1, solution->opaque, 24, digest) < 0,
735- -1, "Building of SHA1 Random seed I failed\n");
736-
737- memcpy(puzzle_input.puzzle,
738- &digest[HIP_AH_SHA_LEN - PUZZLE_LENGTH],
739- PUZZLE_LENGTH);
740- puzzle_input.initiator_hit = initiator_hit;
741- puzzle_input.responder_hit = responder_hit;
742- memcpy(puzzle_input.solution, solution->J, PUZZLE_LENGTH);
743-
744- HIP_IFEL(hip_verify_puzzle_solution(&puzzle_input, solution->K),
745- -1, "Solution is wrong\n");
746-
747-out_err:
748- return err;
749-}
750-
751-/**
752- * Move the last HIP parameter to the correct position according to its
753- * parameter type. Will probably break the packet if something is moved in
754- * front of a signature.
755- *
756- * @param hip the HIP packet
757- * @return 0 on success
758- */
759-static int midauth_relocate_last_hip_parameter(struct hip_common *hip)
760-{
761- int err = 0, len, total_len, offset;
762- char buffer[HIP_MAX_PACKET], *ptr = (char *) hip;
763- struct hip_tlv_common *i = NULL, *last = NULL;
764- hip_tlv type;
765-
766- while ((i = hip_get_next_param_readwrite(hip, i))) {
767- last = i;
768- }
769-
770- HIP_IFEL(last == NULL, -1, "Trying to relocate in an empty packet!\n");
771-
772- total_len = hip_get_msg_total_len(hip);
773- len = hip_get_param_total_len(last);
774- type = hip_get_param_type(last);
775-
776- HIP_IFEL(len > (int) sizeof(buffer), -1,
777- "Last parameter's length exceeds HIP_MAX_PACKET\n");
778-
779- /* @todo check for signature parameter to avoid broken packets */
780-
781- memcpy(buffer, last, len);
782- i = NULL;
783-
784- while ((i = hip_get_next_param_readwrite(hip, i))) {
785- if (hip_get_param_type(i) > type) {
786- offset = (char *) i - (char *) hip;
787-
788- memmove(ptr + offset + len, ptr + offset,
789- total_len - offset - len);
790- memcpy(ptr + offset, buffer, len);
791- break;
792- }
793- }
794-
795-out_err:
796- return err;
797-}
798-
799-/**
800- * Creates a challenge request and adds it to a forwarded HIP
801- * packet.
802- *
803- * @param ctx connection context of the modified packet
804- * @param val_K puzzle difficulty
805- * @param ltime lifetime of the challenge in s
806- * @param opaque contents of the opaque data field
807- * @param opaque_len length of the opaque data field
808- * @return 0 on success, <0 otherwise
809- */
810-int midauth_add_challenge_request(struct hip_fw_context *ctx, uint8_t val_K,
811- uint8_t ltime,
812- uint8_t *opaque,
813- uint8_t opaque_len)
814-{
815- struct hip_common *hip = ctx->transport_hdr.hip;
816- int err = 0;
817-
818- ctx->modified = 1;
819-
820- HIP_IFEL(hip_build_param_challenge_request(hip, val_K, ltime,
821- opaque, opaque_len),
822- -1, "Failed to build challenge_request parameter\n");
823- HIP_IFEL(midauth_relocate_last_hip_parameter(hip), -1,
824- "Failed to relocate new challenge_request parameter\n");
825-
826-out_err:
827- return err;
828-}
829-
830-int midauth_handler_accept(UNUSED struct hip_fw_context *ctx)
831-{
832- return NF_ACCEPT;
833-}
834-
835-/**
836- * Drops a packet. Used in midauth_handlers as a default handler.
837- *
838- * @param ctx context of the packet
839- * @return NF_DROP
840- */
841-static int midauth_handler_drop(UNUSED struct hip_fw_context *ctx)
842-{
843- return NF_DROP;
844-}
845-
846-/**
847- * Distinguish the different UPDATE packets.
848- *
849- * @param ctx context of the modified packet
850- * @return the verdict, either NF_ACCEPT or NF_DROP
851- */
852-static midauth_handler filter_midauth_update(const struct hip_fw_context *ctx)
853-{
854- if (hip_get_param(ctx->transport_hdr.hip, HIP_PARAM_LOCATOR)) {
855- return handlers.u1;
856- }
857- if (hip_get_param(ctx->transport_hdr.hip, HIP_PARAM_ECHO_REQUEST)) {
858- return handlers.u2;
859- }
860- if (hip_get_param(ctx->transport_hdr.hip, HIP_PARAM_ECHO_RESPONSE)) {
861- return handlers.u3;
862- }
863-
864- HIP_ERROR("Unknown UPDATE format, rejecting the request!\n");
865- return midauth_handler_drop;
866-}
867-
868-/**
869- * Packet handler dispatcher function. Classifies packets based on
870- * their type and calls the appropriate type-specific handler functions.
871- *
872- * @param ctx HIP connection context
873- * @return the verdict, either NF_ACCEPT or NF_DROP
874- */
875-int midauth_filter_hip(struct hip_fw_context *ctx)
876-{
877- int verdict = NF_ACCEPT;
878- midauth_handler h = NULL;
879- midauth_handler h_default = midauth_handler_accept;
880- /* @todo change this default value to midauth_handler_drop to
881- * disallow unknown message types */
882-
883- switch (ctx->transport_hdr.hip->type_hdr) {
884- case HIP_I1:
885- h = handlers.i1;
886- break;
887- case HIP_R1:
888- h = handlers.r1;
889- break;
890- case HIP_I2:
891- h = handlers.i2;
892- break;
893- case HIP_R2:
894- h = handlers.r2;
895- break;
896- case HIP_UPDATE:
897- h = filter_midauth_update(ctx);
898- break;
899- case HIP_CLOSE:
900- h = handlers.close;
901- break;
902- case HIP_CLOSE_ACK:
903- h = handlers.close_ack;
904- break;
905- default:
906- HIP_DEBUG("filtering default message type\n");
907- break;
908- }
909-
910- if (!h) {
911- h = h_default;
912- }
913- verdict = h(ctx);
914-
915- /* do not change packet when it is dropped */
916- if (verdict != NF_ACCEPT) {
917- ctx->modified = 0;
918- }
919-
920- /* if packet was modified correct every necessary part */
921- if (ctx->modified != 0) {
922- midauth_update_all_headers(ctx);
923- }
924-
925- return verdict;
926-}
927-
928-/**
929- * Call the initializer functions
930+// static configuration
931+static const bool ignore_missing_challenge_request = false;
932+static const bool ignore_missing_challenge_response = false;
933+static const bool ignore_wrong_challenge_solution = false;
934+static const bool ignore_malformed_update = false;
935+static const bool notify_failed_challenge = true;
936+
937+static const uint8_t DEFAULT_DIFFICULTY = 1;
938+
939+// runtime configuration
940+bool use_midauth = false;
941+
942+/**
943+ * Initialize the midauth extension for the firewall.
944 */
945 void midauth_init(void)
946 {
947- pisa_init(&handlers);
948+ HIP_DEBUG("== midauth enabled ==\n");
949+}
950+
951+/**
952+ * Get the lifetime of a midauth challenge.
953+ *
954+ * @param difficulty The difficulty of the puzzle.
955+ * @return The lifetime of the challenge.
956+ *
957+ * @todo Lifetime should depend on difficulty.
958+ */
959+static inline uint8_t lifetime(UNUSED const uint8_t difficulty)
960+{
961+ return 2;
962+}
963+
964+/**
965+ * Add a CHALLENGE_REQUEST parameter to a HIP packet passing through the
966+ * firewall.
967+ *
968+ * @param ctx The packet context.
969+ * @param[out] midauth_nonce The nonce added by the firewall for this handshake.
970+ * @return 1 on success, 0 otherwise
971+ */
972+int hipfw_midauth_add_challenge(struct hip_fw_context *const ctx,
973+ uint8_t midauth_nonce[MIDAUTH_DEFAULT_NONCE_LENGTH])
974+{
975+ struct hip_challenge_request request;
976+ static const size_t min_length = sizeof(request) -
977+ sizeof(request.tlv) -
978+ sizeof(request.opaque);
979+
980+ if (use_midauth) {
981+ HIP_ASSERT(midauth_nonce);
982+ HIP_ASSERT(ctx);
983+ HIP_ASSERT(ctx->packet_type == HIP_PACKET);
984+
985+ /* note: the length cannot be calculated with calc_param_len() */
986+ hip_set_param_contents_len(&request.tlv,
987+ min_length + MIDAUTH_DEFAULT_NONCE_LENGTH);
988+ hip_set_param_type(&request.tlv, HIP_PARAM_CHALLENGE_REQUEST);
989+
990+ request.K = DEFAULT_DIFFICULTY;
991+ request.lifetime = lifetime(DEFAULT_DIFFICULTY);
992+
993+ if (!RAND_bytes(request.opaque, MIDAUTH_DEFAULT_NONCE_LENGTH)) {
994+ HIP_ERROR("Failed to generate CHALLENGE_REQUEST nonce\n");
995+ return ignore_missing_challenge_request;
996+ }
997+
998+ // IP (and UDP, if needed) frames will be updated upon send
999+ // Implicitly calls hip_fw_context_enable_write() if needed
1000+ if (!hipfw_splice_param(ctx, &request.tlv)) {
1001+ HIP_ERROR("Failed to splice CHALLENGE_REQUEST into existing packet\n");
1002+
1003+ // fatality depends on current settings
1004+ return ignore_missing_challenge_request;
1005+ }
1006+
1007+ /* store nonce per-connection per-peer */
1008+ memcpy(midauth_nonce, request.opaque, MIDAUTH_DEFAULT_NONCE_LENGTH);
1009+ }
1010+
1011+ return 1;
1012+}
1013+
1014+/**
1015+ * Getter for the length of the opaque field in a CHALLENGE_REPSONSE parameter.
1016+ *
1017+ * @param response The CHALLENGE_REPSONSE parameter.
1018+ * @return The length of the opaque value.
1019+ */
1020+static uint8_t hip_challenge_response_opaque_len(const struct hip_challenge_response *response)
1021+{
1022+ HIP_ASSERT(response);
1023+ static const size_t min_len = sizeof(*response) -
1024+ sizeof(response->tlv) -
1025+ sizeof(response->opaque);
1026+
1027+ return hip_get_param_contents_len(&response->tlv) - min_len;
1028+}
1029+
1030+enum verification_result {
1031+ ERROR,
1032+ RESPONSE_CORRECT,
1033+ RESPONSE_INCORRECT,
1034+ RESPONSE_NO_MATCH
1035+};
1036+
1037+/**
1038+ * Helper function for verifying a CHALLENGE_RESPONSE parameter.
1039+ *
1040+ * @param ctx The packet context.
1041+ * @param response The CHALLENGE_RESPONSE parameter.
1042+ * @param midauth_nonce The stored nonce for this association.
1043+ * @return ERROR on validation error,
1044+ * RESPONSE_CORRECT if validation was successful,
1045+ * RESPONSE_INCORRECT if nonces match but solution is incorrect, and
1046+ * RESPONSE_NO_MATCH if no matching nonces are stored.
1047+ */
1048+static enum verification_result verify_response(const struct hip_fw_context *const ctx,
1049+ const struct hip_challenge_response *const response,
1050+ const uint8_t midauth_nonce[MIDAUTH_DEFAULT_NONCE_LENGTH])
1051+{
1052+ HIP_ASSERT(ctx);
1053+ HIP_ASSERT(response);
1054+ HIP_ASSERT(midauth_nonce);
1055+
1056+ //
1057+ // TODO: - check lifetime
1058+ // - compare with connection state entry (K, nonce)
1059+ // - use HITs from packet or from ctx?
1060+ //
1061+
1062+ const uint8_t len = hip_challenge_response_opaque_len(response);
1063+ const bool match = (len == MIDAUTH_DEFAULT_NONCE_LENGTH) &&
1064+ (memcmp(response->opaque, midauth_nonce,
1065+ MIDAUTH_DEFAULT_NONCE_LENGTH) == 0);
1066+
1067+ if (!match) {
1068+ return RESPONSE_NO_MATCH;
1069+ }
1070+
1071+ if (response->K < DEFAULT_DIFFICULTY) {
1072+ return RESPONSE_INCORRECT;
1073+ }
1074+
1075+ const struct hip_common *const hip = ctx->transport_hdr.hip;
1076+
1077+ if (response->K > 0) {
1078+ struct puzzle_hash_input tmp_puzzle;
1079+
1080+ if (hip_midauth_puzzle_seed(response->opaque, len, tmp_puzzle.puzzle)) {
1081+ HIP_ERROR("failed to derive midauth puzzle\n");
1082+ return ERROR;
1083+ }
1084+ tmp_puzzle.initiator_hit = hip->hits;
1085+ tmp_puzzle.responder_hit = hip->hitr;
1086+ memcpy(tmp_puzzle.solution, response->J, PUZZLE_LENGTH);
1087+
1088+ if (hip_verify_puzzle_solution(&tmp_puzzle, response->K)) {
1089+ return RESPONSE_INCORRECT;
1090+ }
1091+ }
1092+
1093+ return RESPONSE_CORRECT;
1094+}
1095+
1096+/**
1097+ * Verify a puzzle solution in the CHALLENGE_RESPONSE parameter.
1098+ *
1099+ * @param ctx The packet context.
1100+ * @param midauth_nonce The stored nonce for this association.
1101+ * @return 1 on success, 0 otherwise
1102+ */
1103+int hipfw_midauth_verify_challenge(const struct hip_fw_context *const ctx,
1104+ const uint8_t midauth_nonce[MIDAUTH_DEFAULT_NONCE_LENGTH])
1105+{
1106+ const struct hip_challenge_response *response;
1107+
1108+ HIP_ASSERT(ctx);
1109+
1110+ if (use_midauth) {
1111+ HIP_ASSERT(ctx->packet_type == HIP_PACKET);
1112+
1113+ response = hip_get_param(ctx->transport_hdr.hip,
1114+ HIP_PARAM_CHALLENGE_RESPONSE);
1115+ if (!response) {
1116+ HIP_ERROR("Challenge response expected but not found\n");
1117+ return ignore_missing_challenge_response ? 1 : 0;
1118+ }
1119+
1120+ bool found = false;
1121+ do {
1122+ switch (verify_response(ctx, response, midauth_nonce)) {
1123+ case RESPONSE_CORRECT:
1124+ HIP_DEBUG("Correct CHALLENGE_RESPONSE found\n");
1125+ return 1;
1126+ case RESPONSE_INCORRECT:
1127+ HIP_ERROR("Incorrect CHALLENGE_RESPONSE found\n");
1128+ if (notify_failed_challenge) {
1129+ // TODO: notify peer (ICMP, HIP notify)
1130+ HIP_DEBUG("STUB: notify\n");
1131+ }
1132+
1133+ if (!ignore_wrong_challenge_solution) {
1134+ return 0;
1135+ }
1136+ break;
1137+ case RESPONSE_NO_MATCH:
1138+ break;
1139+ default:
1140+ HIP_ERROR("Unable to compute challenge verification.\n");
1141+ break;
1142+ }
1143+
1144+ response = (const struct hip_challenge_response *)
1145+ hip_get_next_param(ctx->transport_hdr.hip, &response->tlv);
1146+ } while (response &&
1147+ hip_get_param_type(response) == HIP_PARAM_CHALLENGE_RESPONSE);
1148+
1149+ if (!found) {
1150+ HIP_ERROR("CHALLENGE_RESPONSE found, but no matching nonce\n");
1151+ return ignore_missing_challenge_response ? 1 : 0;
1152+ }
1153+
1154+ return found ? 1 : 0;
1155+ }
1156+
1157+ return 1;
1158 }
1159
1160=== modified file 'firewall/midauth.h'
1161--- firewall/midauth.h 2011-08-15 14:11:56 +0000
1162+++ firewall/midauth.h 2011-10-25 12:58:23 +0000
1163@@ -29,58 +29,19 @@
1164 #define _BSD_SOURCE
1165
1166 #include <stdint.h>
1167-
1168-#include "lib/core/protodefs.h"
1169-#include "modules/midauth/lib/midauth_builder.h"
1170+#include <stdbool.h>
1171+
1172+#define MIDAUTH_DEFAULT_NONCE_LENGTH 18
1173+
1174 #include "firewall_defines.h"
1175
1176-typedef int (*midauth_handler)(struct hip_fw_context *ctx);
1177-
1178-struct midauth_handlers {
1179- midauth_handler i1;
1180- midauth_handler r1;
1181- midauth_handler i2;
1182- midauth_handler r2;
1183- midauth_handler u1;
1184- midauth_handler u2;
1185- midauth_handler u3;
1186- midauth_handler close;
1187- midauth_handler close_ack;
1188-};
1189-
1190-/**
1191- * Accepts a packet. Used in midauth_handlers as a default handler.
1192- *
1193- * @param ctx context of the packet
1194- * @return NF_ACCEPT
1195- */
1196-int midauth_handler_accept(struct hip_fw_context *ctx);
1197-
1198-int midauth_verify_challenge_response(const struct hip_challenge_response *const solution,
1199- const hip_hit_t initiator_hit,
1200- const hip_hit_t responder_hit);
1201-
1202-
1203-
1204-/**
1205- * Insert a CHALLENGE_REQUEST parameter into a HIP packet.
1206- *
1207- * @param ctx context of the packet to be modified
1208- * @param val_K challenge_request parameter val_K
1209- * @param ltime challenge_request parameter lifetime
1210- * @param opaque challenge_request parameter opaque
1211- * @param opaque_len length of opaque
1212- * @return 0 on success
1213- */
1214-int midauth_add_challenge_request(struct hip_fw_context *ctx,
1215- uint8_t val_K, uint8_t ltime,
1216- uint8_t *opaque, uint8_t opaque_len);
1217-
1218-/**
1219- * Initialize midauth infrastructure.
1220- */
1221+extern bool use_midauth;
1222+
1223 void midauth_init(void);
1224
1225-int midauth_filter_hip(struct hip_fw_context *ctx);
1226+int hipfw_midauth_add_challenge(struct hip_fw_context *const ctx,
1227+ uint8_t *const midauth_nonce);
1228+int hipfw_midauth_verify_challenge(const struct hip_fw_context *const ctx,
1229+ const uint8_t *const midauth_nonce);
1230
1231 #endif /* HIP_FIREWALL_MIDAUTH_H */
1232
1233=== modified file 'firewall/pisa.h'
1234--- firewall/pisa.h 2011-08-15 14:11:56 +0000
1235+++ firewall/pisa.h 2011-10-25 12:58:23 +0000
1236@@ -31,12 +31,14 @@
1237 #define PISA_STATE_DISALLOW 0
1238 #define PISA_STATE_ALLOW 1
1239
1240+#ifdef CONFIG_HIP_PISA
1241 /**
1242 * Register PISA handlers with midauth and initialize data structures.
1243 *
1244 * @param h pointer to the handlers
1245 */
1246 void pisa_init(struct midauth_handlers *h);
1247+#endif
1248
1249 /**
1250 * Check if a new random number is necessary.
1251
1252=== added file 'firewall/rewrite.c'
1253--- firewall/rewrite.c 1970-01-01 00:00:00 +0000
1254+++ firewall/rewrite.c 2011-10-25 12:58:23 +0000
1255@@ -0,0 +1,380 @@
1256+/*
1257+ * Copyright (c) 2011 Aalto University and RWTH Aachen University.
1258+ *
1259+ * Permission is hereby granted, free of charge, to any person
1260+ * obtaining a copy of this software and associated documentation
1261+ * files (the "Software"), to deal in the Software without
1262+ * restriction, including without limitation the rights to use,
1263+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
1264+ * copies of the Software, and to permit persons to whom the
1265+ * Software is furnished to do so, subject to the following
1266+ * conditions:
1267+ *
1268+ * The above copyright notice and this permission notice shall be
1269+ * included in all copies or substantial portions of the Software.
1270+ *
1271+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1272+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
1273+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
1274+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
1275+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
1276+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
1277+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
1278+ * OTHER DEALINGS IN THE SOFTWARE.
1279+ */
1280+
1281+/**
1282+ * @file
1283+ *
1284+ * Support and utility functions for packet rewriting, especially for growing
1285+ * packets.
1286+ *
1287+ * Note that the buffer supplied to ipq_get_packet() in the firewall main loop
1288+ * is not big enough to hold both the ipq_packet header and ::HIP_MAX_PACKET
1289+ * bytes of payload.
1290+ * Furthermore, the actual amount of writable data behind the received payload
1291+ * is not documented by the libipq team. This makes sense if you consider that
1292+ * netlink is able to push multiple packets into our userspace buffer for
1293+ * efficiency reasons. Unfortunately, it is not documented whether libipq
1294+ * actually makes use of this feature either.
1295+ *
1296+ * For this reason, all packet rewriting that needs access beyond the boundaries
1297+ * of the originally received packet should copy it into a big, temporary buffer
1298+ * first. This is managed by the hip_fw_context_enable_write() function; see its
1299+ * documentation for more info.
1300+ *
1301+ * After growing, the data_len field and the length of the innermost frame
1302+ * (currently either HIP oder ESP) must be updated: Checksums and outer length
1303+ * fields are updated only once, right before reinjecting the packet.
1304+ *
1305+ * @note Copying the packet incurs a considerable performance hit. Browsing the
1306+ * source code of libipq, netfilter_queue and netlink, one can find
1307+ * assumptions about the original buffer and its usage to save copying in
1308+ * some cases, but unless the internals of these interfaces are documented
1309+ * more thoroughly, these optimizations should be considered hacks (and
1310+ * are thus not used here).
1311+ *
1312+ * @author Christof Mroz <christof.mroz@rwth-aachen.de>
1313+ */
1314+
1315+#define _BSD_SOURCE
1316+
1317+#include <netinet/in.h>
1318+#include <linux/netfilter.h>
1319+#include <libipq.h>
1320+#include <limits.h>
1321+#include <stdlib.h>
1322+#include <string.h>
1323+
1324+#include "lib/core/builder.h"
1325+#include "lib/core/debug.h"
1326+#include "lib/tool/checksum.h"
1327+#include "rewrite.h"
1328+
1329+// static configuration
1330+static const bool assume_ipq_buffer_sufficient = false;
1331+
1332+struct scratch_buffer {
1333+ ipq_packet_msg_t ipq;
1334+ uint8_t *payload[HIP_MAX_PACKET];
1335+} __attribute__((packed)); // no gaps between header and payload
1336+
1337+static struct scratch_buffer scratch_buffer;
1338+
1339+/**
1340+ * Given the address @a field of a struct member of @a old, return
1341+ * the same field's address but offset from @a new.
1342+ *
1343+ * As an example use case, say we have a pointer into @a old:
1344+ * <code>
1345+ * char old[LEN];
1346+ * ptr = &old[BLA];
1347+ * </code>
1348+ * Now after copying @a old to @a new, we need to update the pointer:
1349+ * <code>
1350+ * ptr = rebase(ptr, old, new);
1351+ * </code>
1352+ *
1353+ * @note This is essentially equivalent to
1354+ * <code>
1355+ * return &new.field
1356+ * </code>
1357+ * But of course, the above can only be used if we actually know
1358+ * the name of @a field, while this function needs just the
1359+ * address and base pointer.
1360+ */
1361+static void *rebase(const void *const field,
1362+ const void *const old,
1363+ void *const new)
1364+{
1365+ HIP_ASSERT((const char *) field >= (const char *) old);
1366+ return (char *) new + ((const char *) field - (const char *) old);
1367+}
1368+
1369+/**
1370+ * Mark packet as modified and indicate that the packet buffer passed by libipq
1371+ * is overwritten with packet content.
1372+ *
1373+ * @param ctx The current packet context.
1374+ *
1375+ * @note Only set this flag when sure that the new packet will not exceed the
1376+ * buffer length of the packet originally passed by libipq.
1377+ */
1378+static void hip_fw_context_enable_write_inplace(struct hip_fw_context *const ctx)
1379+{
1380+ ctx->modified = 1;
1381+}
1382+
1383+/**
1384+ * Mark packet as modified and enable rewritten packet to grow up to
1385+ * ::HIP_MAX_PACKET bytes.
1386+ * The buffer will be available via the ipq_packet->payload member of @a ctx, as
1387+ * usual. That is: To the caller, it should look like nothing happened.
1388+ *
1389+ * @param ctx The current packet context. The ipq header may have been modified
1390+ * but should be consistent, especially the data_len field.
1391+ *
1392+ * @note It is safe to call this function on the same @a ctx multiple times: the
1393+ * packet will not needlessly be copied again.
1394+ */
1395+static void hip_fw_context_enable_write(struct hip_fw_context *const ctx)
1396+{
1397+ HIP_ASSERT(ctx);
1398+ HIP_ASSERT(ctx->ipq_packet);
1399+
1400+ if (assume_ipq_buffer_sufficient) {
1401+ hip_fw_context_enable_write_inplace(ctx);
1402+ return;
1403+ }
1404+
1405+ if (ctx->ipq_packet != &scratch_buffer.ipq) {
1406+ // simply rebase the old pointers
1407+ if (ctx->ip_version == 4) {
1408+ ctx->ip_hdr.ipv4 = rebase(ctx->ip_hdr.ipv4, ctx->ipq_packet,
1409+ &scratch_buffer.ipq);
1410+ } else {
1411+ HIP_ASSERT(ctx->ip_version == 6);
1412+ ctx->ip_hdr.ipv6 = rebase(ctx->ip_hdr.ipv6, ctx->ipq_packet,
1413+ &scratch_buffer.ipq);
1414+ }
1415+
1416+ switch (ctx->packet_type) {
1417+ case ESP_PACKET:
1418+ ctx->transport_hdr.esp = rebase(ctx->transport_hdr.esp, ctx->ipq_packet,
1419+ &scratch_buffer.ipq);
1420+ break;
1421+ case HIP_PACKET:
1422+ ctx->transport_hdr.hip = rebase(ctx->transport_hdr.hip, ctx->ipq_packet,
1423+ &scratch_buffer.ipq);
1424+ break;
1425+ case OTHER_PACKET:
1426+ break;
1427+ default:
1428+ HIP_ASSERT(false);
1429+ }
1430+
1431+ if (ctx->udp_encap_hdr) {
1432+ ctx->udp_encap_hdr = rebase(ctx->udp_encap_hdr, ctx->ipq_packet,
1433+ &scratch_buffer.ipq);
1434+ }
1435+
1436+ // copy ipq packet plus payload
1437+ memcpy(&scratch_buffer.ipq, ctx->ipq_packet,
1438+ sizeof(*ctx->ipq_packet) + ctx->ipq_packet->data_len);
1439+ ctx->ipq_packet = &scratch_buffer.ipq;
1440+ ctx->modified = 1;
1441+ } else {
1442+ // second invocation
1443+ HIP_ASSERT(ctx->modified);
1444+ }
1445+}
1446+
1447+/**
1448+ * Add a new parameter to the correct position in the packet. Parameters are
1449+ * ordered by type number. Hence, some parameters might need to be moved in
1450+ * order for the new parameter to fit into the right position.
1451+ *
1452+ * @param ctx The current packet context.
1453+ * @param param The parameter to be added to the packet.
1454+ * @return true on success, false otherwise.
1455+ */
1456+bool hipfw_splice_param(struct hip_fw_context *const ctx,
1457+ const struct hip_tlv_common *const param)
1458+{
1459+ HIP_ASSERT(ctx);
1460+ HIP_ASSERT(ctx->packet_type == HIP_PACKET);
1461+ HIP_ASSERT(param);
1462+
1463+ const size_t hip_len = hip_get_msg_total_len(ctx->transport_hdr.hip); // padded
1464+ const size_t param_len = hip_get_param_total_len(param); // padded
1465+ const hip_tlv param_type = hip_get_param_type(param);
1466+ const size_t contents_len = hip_get_param_contents_len(param); // not padded
1467+
1468+ // RFC 5201: Types 0 - 1023 are signed, so they must not be moved
1469+ HIP_ASSERT(param_type >= 1024);
1470+
1471+ if (ctx->ipq_packet->data_len + param_len > sizeof(scratch_buffer.payload)) {
1472+ HIP_ERROR("New parameter of type %u, effective size %u, "
1473+ "does not fit into packet", param_type, param_len);
1474+ return false;
1475+ }
1476+
1477+ hip_fw_context_enable_write(ctx);
1478+
1479+ // note: this works because param_len is padded! otherwise, resize the hip
1480+ // packet and call hip_get_msg_total_len() instead.
1481+ ctx->ipq_packet->data_len += param_len;
1482+
1483+ struct hip_common *const hip = ctx->transport_hdr.hip;
1484+ uint8_t *const end = ((uint8_t *) hip) + hip_len;
1485+ struct hip_tlv_common *current = NULL;
1486+ uint8_t *out = end; // append by default
1487+
1488+ while ((current = hip_get_next_param_readwrite(hip, current))) {
1489+ if (hip_get_param_type(current) >= param_type) {
1490+ uint8_t *const splice = (uint8_t *const) current;
1491+
1492+ memmove(splice + param_len, splice, end - splice);
1493+ out = splice;
1494+ break;
1495+ }
1496+ }
1497+
1498+ if ((sizeof(struct hip_tlv_common) + contents_len) != param_len) {
1499+ // padding needed: don't send uninitialized data
1500+ memset(out, 0, param_len);
1501+ }
1502+
1503+ memcpy(out, param, sizeof(struct hip_tlv_common) + contents_len);
1504+ hip_set_msg_total_len(hip, hip_len + param_len); // IP length etc. will be inferred
1505+
1506+ return true;
1507+}
1508+
1509+/**
1510+ * Getter for the position of the IP payload in an IPv4 packet. This allows to
1511+ * handle IP options.
1512+ *
1513+ * @param ipv4 The IPv4 packet.
1514+ */
1515+inline static void *get_ipv4_payload(struct ip *const ipv4)
1516+{
1517+ return ((uint8_t *) ipv4) + 4 * ipv4->ip_hl;
1518+}
1519+
1520+/**
1521+ * Update the UDP header after modifying the higher layer packet content.
1522+ *
1523+ * @param udp The UDP packet.
1524+ * @param payload_len The length of the UDP payload.
1525+ * @param src_ip The source IP address (needed for pseudo-header).
1526+ * @param dst_ip The destination IP address (needed for pseudo-header).
1527+ */
1528+static void update_udp_header(struct udphdr *const udp,
1529+ const size_t payload_len,
1530+ const struct in_addr src_ip,
1531+ const struct in_addr dst_ip)
1532+{
1533+ const uint16_t tot_len = sizeof(*udp) + payload_len;
1534+
1535+ HIP_ASSERT(sizeof(*udp) == 8);
1536+
1537+ udp->len = htons(tot_len);
1538+ udp->check = htons(0);
1539+ udp->check = ipv4_checksum(IPPROTO_UDP, &src_ip, &dst_ip, udp, tot_len);
1540+}
1541+
1542+/**
1543+ * Update the IPv4 header after modifying the higher layer packet content.
1544+ *
1545+ * @param ipv4 The IPv4 packet.
1546+ * @param payload_len The length of the IPv4 payload.
1547+ */
1548+static void update_ipv4_header(struct ip *const ipv4,
1549+ const size_t payload_len)
1550+{
1551+ ipv4->ip_len = htons(ipv4->ip_hl * 4 + payload_len);
1552+ ipv4->ip_sum = htons(0);
1553+ ipv4->ip_sum = checksum_ip(ipv4, ipv4->ip_hl);
1554+}
1555+
1556+/**
1557+ * Update the IPv6 header after modifying the higher layer packet content.
1558+ *
1559+ * @param ipv6 The IPv6 packet.
1560+ * @param payload_len The length of the IPv6 payload.
1561+ */
1562+static void update_ipv6_header(struct ip6_hdr *const ipv6,
1563+ const size_t payload_len)
1564+{
1565+ ipv6->ip6_plen = htons(payload_len);
1566+}
1567+
1568+/**
1569+ * Set an accept verdict for a modified packet
1570+ *
1571+ * @param handle libipq file handle
1572+ * @param ctx The current packet context.
1573+ *
1574+ */
1575+void allow_modified_packet(struct ipq_handle *const handle,
1576+ struct hip_fw_context *const ctx)
1577+{
1578+ HIP_ASSERT(ctx->modified);
1579+
1580+ //
1581+ // TODO: send as separate packets if fragmented?
1582+ //
1583+
1584+ if (ctx->packet_type == HIP_PACKET) {
1585+ struct hip_common *const hip = ctx->transport_hdr.hip;
1586+ const size_t hip_len = hip_get_msg_total_len(hip);
1587+
1588+ if (ctx->ip_version == 4) {
1589+ struct ip *const ipv4 = ctx->ip_hdr.ipv4;
1590+
1591+ if (ipv4->ip_p == IPPROTO_UDP) {
1592+ // UDP Payload: "zero SPI" (0x00000000) + HIP
1593+ const size_t udp_len = HIP_UDP_ZERO_BYTES_LEN + hip_len;
1594+
1595+ update_udp_header(get_ipv4_payload(ipv4), udp_len,
1596+ ipv4->ip_src, ipv4->ip_dst);
1597+ update_ipv4_header(ipv4, sizeof(struct udphdr) + udp_len);
1598+ // HIP checksum unused
1599+ } else {
1600+ const struct sockaddr_in src = { .sin_family = AF_INET,
1601+ .sin_addr = ipv4->ip_src };
1602+ const struct sockaddr_in dst = { .sin_family = AF_INET,
1603+ .sin_addr = ipv4->ip_dst };
1604+
1605+ HIP_ASSERT(ipv4->ip_p == IPPROTO_HIP);
1606+
1607+ hip_zero_msg_checksum(hip);
1608+ hip->checksum = hip_checksum_packet((char *) hip,
1609+ (const struct sockaddr *) &src,
1610+ (const struct sockaddr *) &dst);
1611+ update_ipv4_header(ipv4, hip_len);
1612+ }
1613+ } else {
1614+ HIP_ASSERT(ctx->ip_version == 6);
1615+
1616+ struct ip6_hdr *const ipv6 = ctx->ip_hdr.ipv6;
1617+ const struct sockaddr_in6 src = { .sin6_family = AF_INET6,
1618+ .sin6_addr = ipv6->ip6_src };
1619+ const struct sockaddr_in6 dst = { .sin6_family = AF_INET6,
1620+ .sin6_addr = ipv6->ip6_dst };
1621+
1622+ HIP_ASSERT(ipv6->ip6_nxt == IPPROTO_HIP);
1623+
1624+ hip_zero_msg_checksum(hip);
1625+ hip->checksum = hip_checksum_packet((char *) hip,
1626+ (const struct sockaddr *) &src,
1627+ (const struct sockaddr *) &dst);
1628+ update_ipv6_header(ipv6, hip_len);
1629+ }
1630+ }
1631+
1632+ ipq_set_verdict(handle, ctx->ipq_packet->packet_id, NF_ACCEPT,
1633+ ctx->ipq_packet->data_len, ctx->ipq_packet->payload);
1634+ HIP_DEBUG("Packet accepted with modifications\n\n");
1635+}
1636
1637=== added file 'firewall/rewrite.h'
1638--- firewall/rewrite.h 1970-01-01 00:00:00 +0000
1639+++ firewall/rewrite.h 2011-10-25 12:58:23 +0000
1640@@ -0,0 +1,39 @@
1641+/*
1642+ * Copyright (c) 2011 Aalto University and RWTH Aachen University.
1643+ *
1644+ * Permission is hereby granted, free of charge, to any person
1645+ * obtaining a copy of this software and associated documentation
1646+ * files (the "Software"), to deal in the Software without
1647+ * restriction, including without limitation the rights to use,
1648+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
1649+ * copies of the Software, and to permit persons to whom the
1650+ * Software is furnished to do so, subject to the following
1651+ * conditions:
1652+ *
1653+ * The above copyright notice and this permission notice shall be
1654+ * included in all copies or substantial portions of the Software.
1655+ *
1656+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1657+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
1658+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
1659+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
1660+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
1661+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
1662+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
1663+ * OTHER DEALINGS IN THE SOFTWARE.
1664+ */
1665+
1666+#ifndef HIP_FIREWALL_REWRITE_H
1667+#define HIP_FIREWALL_REWRITE_H
1668+
1669+#include <stdbool.h>
1670+
1671+#include "firewall_defines.h"
1672+
1673+
1674+bool hipfw_splice_param(struct hip_fw_context *const ctx,
1675+ const struct hip_tlv_common *const param);
1676+void allow_modified_packet(struct ipq_handle *const handle,
1677+ struct hip_fw_context *const ctx);
1678+
1679+#endif /* HIP_FIREWALL_REWRITE_H */
1680
1681=== modified file 'lib/tool/checksum.c'
1682--- lib/tool/checksum.c 2011-08-15 14:11:56 +0000
1683+++ lib/tool/checksum.c 2011-10-25 12:58:23 +0000
1684@@ -57,15 +57,18 @@
1685 * @param protocol protocol
1686 * @return the calculated IPv4 header checksum
1687 */
1688-uint16_t ipv4_checksum(uint8_t protocol, void *s, void *d, void *c,
1689- uint16_t len)
1690+uint16_t ipv4_checksum(const uint8_t protocol,
1691+ const void *const s,
1692+ const void *const d,
1693+ const void *const c,
1694+ const uint16_t len)
1695 {
1696- uint8_t *src = s;
1697- uint8_t *dst = d;
1698- uint8_t *data = c;
1699- uint16_t word16;
1700- uint32_t sum;
1701- uint16_t i;
1702+ const uint8_t *src = s;
1703+ const uint8_t *dst = d;
1704+ const uint8_t *data = c;
1705+ uint16_t word16;
1706+ uint32_t sum;
1707+ uint16_t i;
1708
1709 /* initialize sum to zero */
1710 sum = 0;
1711@@ -219,23 +222,23 @@
1712 * @return the checksum
1713 * @note Checksumming is from Boeing's HIPD.
1714 */
1715-uint16_t hip_checksum_packet(char *data, struct sockaddr *src,
1716- struct sockaddr *dst)
1717+uint16_t hip_checksum_packet(char *data, const struct sockaddr *src,
1718+ const struct sockaddr *dst)
1719 {
1720- uint16_t checksum = 0;
1721- unsigned long sum = 0;
1722- int count = 0, length = 0;
1723- unsigned short *p = NULL; /* 16-bit */
1724- struct pseudo_header pseudoh;
1725- struct pseudo_header6 pseudoh6;
1726- uint32_t src_network, dst_network;
1727- struct in6_addr *src6, *dst6;
1728- struct hip_common *hiph = (struct hip_common *) data;
1729+ uint16_t checksum = 0;
1730+ unsigned long sum = 0;
1731+ int count = 0, length = 0;
1732+ unsigned short *p = NULL; /* 16-bit */
1733+ struct pseudo_header pseudoh;
1734+ struct pseudo_header6 pseudoh6;
1735+ uint32_t src_network, dst_network;
1736+ const struct in6_addr *src6, *dst6;
1737+ struct hip_common *hiph = (struct hip_common *) data;
1738
1739 if (src->sa_family == AF_INET) {
1740 /* IPv4 checksum based on UDP-- Section 6.1.2 */
1741- src_network = ((struct sockaddr_in *) src)->sin_addr.s_addr;
1742- dst_network = ((struct sockaddr_in *) dst)->sin_addr.s_addr;
1743+ src_network = ((const struct sockaddr_in *) src)->sin_addr.s_addr;
1744+ dst_network = ((const struct sockaddr_in *) dst)->sin_addr.s_addr;
1745
1746 memset(&pseudoh, 0, sizeof(struct pseudo_header));
1747 memcpy(&pseudoh.src_addr, &src_network, 4);
1748@@ -248,8 +251,8 @@
1749 p = (unsigned short *) &pseudoh;
1750 } else {
1751 /* IPv6 checksum based on IPv6 pseudo-header */
1752- src6 = &((struct sockaddr_in6 *) src)->sin6_addr;
1753- dst6 = &((struct sockaddr_in6 *) dst)->sin6_addr;
1754+ src6 = &((const struct sockaddr_in6 *) src)->sin6_addr;
1755+ dst6 = &((const struct sockaddr_in6 *) dst)->sin6_addr;
1756
1757 memset(&pseudoh6, 0, sizeof(struct pseudo_header6));
1758 memcpy(&pseudoh6.src_addr[0], src6, 16);
1759
1760=== modified file 'lib/tool/checksum.h'
1761--- lib/tool/checksum.h 2010-07-16 17:39:09 +0000
1762+++ lib/tool/checksum.h 2011-10-25 12:58:23 +0000
1763@@ -8,13 +8,16 @@
1764 #include <netinet/ip.h>
1765 #include <sys/socket.h>
1766
1767-uint16_t ipv4_checksum(uint8_t protocol, void *s, void *d, void *c, uint16_t len);
1768+uint16_t ipv4_checksum(const uint8_t protocol, const void *const s,
1769+ const void *const d, const void *const c,
1770+ const uint16_t len);
1771 uint16_t ipv6_checksum(uint8_t protocol,
1772 struct in6_addr *src,
1773 struct in6_addr *dst,
1774 void *data, uint16_t len);
1775 uint16_t checksum_ip(struct ip *ip_hdr, const unsigned int ip_hl);
1776 uint16_t inchksum(const void *data, uint32_t length);
1777-uint16_t hip_checksum_packet(char *data, struct sockaddr *src, struct sockaddr *dst);
1778+uint16_t hip_checksum_packet(char *data, const struct sockaddr *src,
1779+ const struct sockaddr *dst);
1780
1781 #endif /* HIP_LIB_TOOL_CHECKSUM_H */
1782
1783=== modified file 'packaging/openwrt/hipl/files/hipfw.init'
1784--- packaging/openwrt/hipl/files/hipfw.init 2011-06-15 12:45:43 +0000
1785+++ packaging/openwrt/hipl/files/hipfw.init 2011-10-25 12:58:23 +0000
1786@@ -4,7 +4,7 @@
1787 START=65
1788 STOP=65
1789
1790-HIPFW_START='hipfw -kb'
1791+HIPFW_START='hipfw -kbm'
1792 PID_FILE="/var/lock/hip_firewall.lock"
1793
1794 # check if daemon is already running
1795
1796=== modified file 'test/check_firewall.c'
1797--- test/check_firewall.c 2011-04-04 16:36:55 +0000
1798+++ test/check_firewall.c 2011-10-25 12:58:23 +0000
1799@@ -36,7 +36,9 @@
1800 srunner_add_suite(sr, firewall_file_buffer());
1801 srunner_add_suite(sr, firewall_helpers());
1802 srunner_add_suite(sr, firewall_line_parser());
1803+ srunner_add_suite(sr, firewall_midauth());
1804 srunner_add_suite(sr, firewall_port_bindings());
1805+ srunner_add_suite(sr, firewall_rewrite());
1806
1807 srunner_run_all(sr, CK_NORMAL);
1808 number_failed = srunner_ntests_failed(sr);
1809
1810=== added file 'test/firewall/midauth.c'
1811--- test/firewall/midauth.c 1970-01-01 00:00:00 +0000
1812+++ test/firewall/midauth.c 2011-10-25 12:58:23 +0000
1813@@ -0,0 +1,298 @@
1814+/*
1815+ * Copyright (c) 2011 Aalto University and RWTH Aachen University.
1816+ *
1817+ * Permission is hereby granted, free of charge, to any person
1818+ * obtaining a copy of this software and associated documentation
1819+ * files (the "Software"), to deal in the Software without
1820+ * restriction, including without limitation the rights to use,
1821+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
1822+ * copies of the Software, and to permit persons to whom the
1823+ * Software is furnished to do so, subject to the following
1824+ * conditions:
1825+ *
1826+ * The above copyright notice and this permission notice shall be
1827+ * included in all copies or substantial portions of the Software.
1828+ *
1829+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
1830+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
1831+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
1832+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
1833+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
1834+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
1835+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
1836+ * OTHER DEALINGS IN THE SOFTWARE.
1837+ */
1838+
1839+#define _BSD_SOURCE
1840+
1841+#include "config.h"
1842+#include "firewall/firewall.c"
1843+#include "firewall/firewall_defines.h"
1844+#include "firewall/midauth.h"
1845+#include "firewall/midauth.c"
1846+#include "modules/midauth/lib/midauth_builder.h"
1847+#include "test_suites.h"
1848+#include "test/mocks.h"
1849+
1850+START_TEST(test_hipfw_midauth_add_challenge)
1851+{
1852+ struct hip_fw_context ctx;
1853+ uint8_t midauth_nonce[MIDAUTH_DEFAULT_NONCE_LENGTH];
1854+ const struct hip_challenge_request *challenge = NULL;
1855+ unsigned char buf[] = "\x00\x30\xF9\x16\x00\x88\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x23\x14\x49\x4E\x00\x00\x00\x00"
1856+ "\x93\x28\x06\x00\x00\x00\x00\x00\x02\x00\x00\x00\x65\x74\x68\x32\x00\x00\x00\x00\x00\x00\x00\x00"
1857+ "\x00\x00\x00\x00\x65\x74\x68\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x01\x00"
1858+ "\x06\x08\x00\x27\x79\x45\x6B\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x03\x00\x00\x00\x00\x00\x00"
1859+ "\x45\x00\x03\x18\x00\x00\x40\x00\x3F\x11\x1D\xD3\x0A\x00\x04\x02\x0A\x00\x03\x01\x29\x04\x29\x04"
1860+ "\x03\x04\x00\x00\x00\x00\x00\x00\x3B\x5E\x02\x11\x00\x00\x00\x00\x20\x01\x00\x10\xD5\x79\x52\xA7"
1861+ "\xFA\xC2\x99\x64\xC9\x36\xA9\x40\x20\x01\x00\x19\x9C\x8E\x9A\x92\xD5\x68\xD2\x87\x7F\x3F\x6F\x95"
1862+ "\x01\x01\x00\x0C\x00\x2A\x48\x49\xF3\xAC\x4C\x3F\x25\x09\xCC\x58\x02\x01\x00\xF6\x03\x00\xC0\x33"
1863+ "\xAE\x3C\x0A\x08\xC3\x47\x2B\x46\xB2\xDD\xE7\xFA\x5E\xC7\x5E\x25\xEE\x8B\x4A\xF4\xF2\xEE\xB8\x25"
1864+ "\x7C\x74\x6F\x3C\x1C\x4F\x51\x87\xF3\xF4\x0E\x8E\x88\xDA\xFF\x55\x2D\x51\x4E\xEB\x2F\x4B\x8D\x89"
1865+ "\xE5\xAD\xEA\xD5\x87\x0D\x20\x9C\xF6\x93\x0A\x05\x2A\x29\x52\x05\x91\x84\x70\xF9\xBE\xF2\x87\x04"
1866+ "\x4D\x5C\x7F\xC9\x20\x8D\x76\x22\xEC\xA5\x0D\x6C\x06\xB5\xB2\x30\x76\x01\x52\x4B\xCD\xD8\x41\xAD"
1867+ "\x59\x95\x0B\xE2\xEC\xAF\xC3\x95\xFA\xB1\x3B\xE2\x06\x51\xB0\x4B\x3F\x6C\x61\xDB\xF1\x08\x25\x11"
1868+ "\xBE\xB6\x4B\x39\x6F\x72\x03\x80\x3A\x4A\x86\xFE\xC4\xC0\x9D\x8B\x8E\x88\x99\x06\xF0\x72\x29\xC6"
1869+ "\x66\xA8\x31\x36\x38\x50\x10\x4F\xD5\xF7\xAE\x39\xDD\xB1\x47\x4B\x14\x59\xA5\x21\x1C\x60\x2D\xF0"
1870+ "\xB7\x16\x71\xEA\xA8\x7B\xC5\xD1\x7F\x60\xD2\xE5\x36\xEF\xED\xBC\xE3\x9E\x63\x85\x19\xC5\xE1\x01"
1871+ "\x00\x30\x4E\x9E\x69\x8F\x6E\xFA\xAF\x95\x9F\x55\x78\x25\xE1\x48\x59\x40\x1D\x5A\x14\x5A\xB2\xA3"
1872+ "\x86\x67\x1C\xE9\x80\x5A\x7A\xC0\xE6\xFE\x6D\x96\x2B\xC5\x8C\x54\x20\xAE\x15\xFA\x7B\xEC\xF9\x1C"
1873+ "\x35\xAB\x00\x00\x00\x00\x00\x00\x02\x41\x00\x06\x00\x01\x00\x02\x00\x05\x00\x00\x00\x00\x00\x00"
1874+ "\x02\xC1\x00\xD4\x00\xC8\x10\x08\x02\x02\xFF\x05\x03\x01\x00\x01\xD9\x83\x29\xBE\xF8\x4C\x5A\xCC"
1875+ "\x9B\x71\x0B\x4E\x26\xCE\x2A\x21\x6C\x29\xC0\x2A\x16\x38\xD1\x92\xE3\x1B\x25\x9D\x65\x24\xF5\x83"
1876+ "\x18\x0D\x61\xE7\xA9\x09\x09\x9C\x8F\xBF\xC1\x07\x02\xBF\x62\x0D\x82\x62\x4C\x81\xEB\x3A\xE2\x62"
1877+ "\x19\xEB\x51\x7A\x12\xDF\x24\x37\x5F\x18\xB4\xF1\x28\xD6\x08\xFF\xE0\x6B\x48\x4E\x13\xC1\x61\x1E"
1878+ "\x72\xF1\xD6\x32\xA1\x43\x42\x37\x66\x45\x6F\x4A\x7A\x92\x51\xE0\x98\x1D\x0F\x92\x18\x37\xB7\xCC"
1879+ "\xCC\x84\xF9\x61\x6C\xE8\xF6\xD7\x3D\xF3\x1D\x04\x4F\xD1\x4C\xA8\x78\x63\x73\xAD\x9C\x2B\xBE\x4D"
1880+ "\x25\x1B\xC5\x9C\x5D\x0F\x6C\xC6\x21\x01\xD1\xFA\xAD\x62\x3C\x5E\x17\x46\xF9\x2C\xE8\xC8\xE2\x8A"
1881+ "\xC0\x04\xD6\x72\xBE\x9E\x25\xB6\x25\x3C\x11\x1F\x8A\x9F\xE7\xAC\x8F\xBC\xD3\x76\x36\xEC\x7E\x41"
1882+ "\xB9\xBC\x5D\x8F\xC1\xD9\x82\x99\xEA\x9B\x70\x00\xA0\xEB\x08\x2F\x74\x68\x65\x73\x69\x73\x32\x00"
1883+ "\x0F\xFF\x00\x08\x00\x00\x00\x01\x00\x02\x00\x05\x00\x00\x00\x00\xF0\xC1\x00\xC1\x05\x2D\x6F\xDE"
1884+ "\xF9\xCE\x0F\x79\x4E\xA3\x21\x73\x0E\x84\x22\x55\x0C\xCC\x43\xBD\x73\xD3\xA3\x8E\xE8\xC1\xA3\xB6"
1885+ "\x69\x0C\xF7\x12\xA9\x10\x7E\x56\xED\xA2\x83\x23\x19\x6D\x9C\xF1\x65\x22\xFC\xB1\x3A\x96\xC7\xF3"
1886+ "\x35\x9C\xAF\xC8\x2B\x38\x21\x03\xB7\xAE\x8D\xE3\x2D\x92\x2C\x66\x90\x03\xD9\x44\xC6\xA5\xAF\x4B"
1887+ "\xBB\x65\x3A\x50\x84\x33\x2C\x0B\x3D\x59\xF8\x57\x27\x9C\xB1\xB6\x73\xC5\xEE\xC2\x68\x52\x35\x9C"
1888+ "\x41\xD7\x11\x6E\xEC\xF5\x20\x7D\xB8\xB4\x4E\xDD\x20\x94\xA0\x1B\xD8\x60\x8C\x5F\xC1\xB4\x9C\x3C"
1889+ "\xE8\xA3\x99\x81\x6B\xF9\x0D\xE4\xE6\xD9\x34\xD6\x8A\xB5\xBD\xAA\x66\x43\x13\xE0\x30\x9A\x07\x46"
1890+ "\xCD\x9D\x6F\x63\xFF\x5E\x05\x54\xDC\xA9\x10\x3C\x2D\xDF\x62\xAD\x18\x13\x74\x61\x92\xD3\xF7\x65"
1891+ "\xAD\x34\xB1\x4D\xB5\x65\x62\x8A\xD4\x7C\xBC\xF7\xC1\x29\x0F\x92\xB8\xB3\xC9\x05\x4A\x00\x00";
1892+
1893+ use_midauth = 1;
1894+ mock_ipq = 1;
1895+ mock_ipq_pkt_len = ARRAY_SIZE(buf);
1896+
1897+ HIP_DEBUG("Testing hipfw_midauth_add_challenge with valid inputs \n");
1898+
1899+ fail_unless(hip_fw_init_context(&ctx, buf, 4) == 0, NULL);
1900+
1901+ fail_unless(hipfw_midauth_add_challenge(&ctx, midauth_nonce) == 1, NULL);
1902+ fail_unless((challenge = hip_get_param(ctx.transport_hdr.hip, HIP_PARAM_CHALLENGE_REQUEST)) != NULL, 0);
1903+ fail_unless(memcmp(challenge->opaque, midauth_nonce, MIDAUTH_DEFAULT_NONCE_LENGTH) == 0, NULL);
1904+ fail_unless(challenge->K >= DEFAULT_DIFFICULTY, NULL);
1905+}
1906+END_TEST
1907+
1908+#ifdef HAVE_TCASE_ADD_EXIT_TEST
1909+START_TEST(test_hipfw_midauth_add_challenge_NULL_ctx)
1910+{
1911+ struct hip_fw_context ctx;
1912+
1913+ HIP_DEBUG("Testing NULL nonce \n");
1914+ use_midauth = true;
1915+ hipfw_midauth_add_challenge(&ctx, NULL);
1916+}
1917+END_TEST
1918+
1919+START_TEST(test_hipfw_midauth_add_challenge_NULL_nonce)
1920+{
1921+ uint8_t nonce[18];
1922+
1923+ HIP_DEBUG("Testing NULL ctx \n");
1924+ use_midauth = true;
1925+ hipfw_midauth_add_challenge(NULL, nonce);
1926+}
1927+END_TEST
1928+#endif /* HAVE_TCASE_ADD_EXIT_TEST */
1929+
1930+START_TEST(test_hip_challenge_response_opaque_len)
1931+{
1932+ struct hip_challenge_response response;
1933+
1934+ HIP_DEBUG("Testing hip_challenge_response_opaque_len \n");
1935+
1936+ hip_set_param_contents_len(&response.tlv, 28);
1937+ fail_unless(hip_challenge_response_opaque_len(&response) == 18, NULL);
1938+
1939+ hip_set_param_contents_len(&response.tlv, 11);
1940+ fail_unless(hip_challenge_response_opaque_len(&response) == 1, NULL);
1941+}
1942+END_TEST
1943+
1944+#ifdef HAVE_TCASE_ADD_EXIT_TEST
1945+START_TEST(test_hip_challenge_response_opaque_len_NULL)
1946+{
1947+ HIP_DEBUG("Testing hip_challenge_response_opaque_len on NULL input\n");
1948+ hip_challenge_response_opaque_len(NULL);
1949+}
1950+END_TEST
1951+
1952+START_TEST(test_verify_response_NULL_ctx)
1953+{
1954+ struct hip_challenge_response response;
1955+ uint8_t midauth_nonce[MIDAUTH_DEFAULT_NONCE_LENGTH];
1956+
1957+ verify_response(NULL, &response, midauth_nonce);
1958+}
1959+END_TEST
1960+
1961+START_TEST(test_verify_response_NULL_response)
1962+{
1963+ struct hip_fw_context ctx;
1964+ uint8_t midauth_nonce[MIDAUTH_DEFAULT_NONCE_LENGTH];
1965+
1966+ verify_response(&ctx, NULL, midauth_nonce);
1967+}
1968+END_TEST
1969+
1970+START_TEST(test_verify_response_NULL_nonce)
1971+{
1972+ struct hip_fw_context ctx;
1973+ struct hip_challenge_response response;
1974+
1975+ verify_response(&ctx, &response, NULL);
1976+}
1977+END_TEST
1978+#endif /* HAVE_TCASE_ADD_EXIT_TEST */
1979+
1980+START_TEST(test_verify_response_no_match)
1981+{
1982+ struct hip_fw_context ctx;
1983+ struct hip_challenge_response response;
1984+ uint8_t midauth_nonce[] = "\x01\x41\x01\x14\x05\x00\x48\x49\x0b"
1985+ "\x02\x42\x02\x15\x06\x08\x49\x50\x0d";
1986+
1987+ HIP_DEBUG("Testing verify_response on non-matching inputs\n");
1988+
1989+ hip_set_param_contents_len(&response.tlv, 28);
1990+ memcpy(response.opaque, midauth_nonce, MIDAUTH_DEFAULT_NONCE_LENGTH);
1991+ response.opaque[0]++;
1992+ fail_unless(verify_response(&ctx, &response, midauth_nonce) == 3, NULL);
1993+ response.opaque[0]--;
1994+
1995+ response.opaque[MIDAUTH_DEFAULT_NONCE_LENGTH - 1]++;
1996+ fail_unless(verify_response(&ctx, &response, midauth_nonce) == 3, NULL);
1997+}
1998+END_TEST
1999+
2000+START_TEST(test_verify_response)
2001+{
2002+ int i;
2003+ struct hip_common hip;
2004+ struct hip_fw_context ctx;
2005+ struct hip_challenge_response response;
2006+ struct puzzle_hash_input tmp_puzzle;
2007+ uint8_t midauth_nonce[] = "\x01\x41\x01\x14\x05\x00\x48\x49\x0b"
2008+ "\x02\x42\x02\x15\x06\x08\x49\x50\x0d";
2009+
2010+ HIP_DEBUG("Testing verify_response on valid inputs\n");
2011+
2012+ // build context
2013+ ctx.transport_hdr.hip = &hip;
2014+ hip.hits = in6addr_any;
2015+ hip.hitr = in6addr_any;
2016+
2017+ // build response
2018+ fail_unless(hip_midauth_puzzle_seed(midauth_nonce, MIDAUTH_DEFAULT_NONCE_LENGTH, tmp_puzzle.puzzle) == 0, NULL);
2019+ tmp_puzzle.initiator_hit = in6addr_any;
2020+ tmp_puzzle.responder_hit = in6addr_any;
2021+ hip_set_param_contents_len(&response.tlv, 28);
2022+ memcpy(response.opaque, midauth_nonce, MIDAUTH_DEFAULT_NONCE_LENGTH);
2023+ for (i = 1; i <= 20; i++) {
2024+ HIP_DEBUG("Difficulty: %i \n", i);
2025+ response.K = i;
2026+ fail_unless(hip_solve_puzzle(&tmp_puzzle, response.K) == 0, NULL);
2027+ memcpy(response.J, tmp_puzzle.solution, 8);
2028+ fail_unless(verify_response(&ctx, &response, midauth_nonce) == 1, NULL);
2029+ }
2030+}
2031+END_TEST
2032+
2033+START_TEST(test_hipfw_midauth_verify_challenge_NULL_ctx)
2034+{
2035+ uint8_t midauth_nonce[] = "\x01\x41\x01\x14\x05\x00\x48\x49\x0b"
2036+ "\x02\x42\x02\x15\x06\x08\x49\x50\x0d";
2037+ hipfw_midauth_verify_challenge(NULL, midauth_nonce);
2038+}
2039+END_TEST
2040+
2041+START_TEST(test_hipfw_midauth_verify_challenge_NULL_challenge)
2042+{
2043+ struct hip_fw_context ctx;
2044+ ctx.packet_type = HIP_PACKET;
2045+ use_midauth = true;
2046+ fail_unless(hipfw_midauth_verify_challenge(&ctx, NULL) == 0, NULL);
2047+}
2048+END_TEST
2049+
2050+START_TEST(test_hipfw_midauth_verify_challenge)
2051+{
2052+ struct hip_common *hip;
2053+ struct hip_fw_context ctx;
2054+ struct hip_challenge_request request;
2055+ struct puzzle_hash_input tmp_puzzle;
2056+ uint8_t midauth_nonce[] = "\x01\x41\x01\x14\x05\x00\x48\x49\x0b"
2057+ "\x02\x42\x02\x15\x06\x08\x49\x50\x0d";
2058+
2059+ HIP_DEBUG("Testing verify_response on valid inputs\n");
2060+
2061+ // build context
2062+ hip = hip_msg_alloc();
2063+ hip->hits = in6addr_any;
2064+ hip->hitr = in6addr_any;
2065+ ctx.transport_hdr.hip = hip;
2066+
2067+ // build request
2068+ request.K = 1;
2069+ request.tlv.type = HIP_PARAM_CHALLENGE_REQUEST;
2070+ hip_set_param_contents_len(&request.tlv, 20);
2071+ memcpy(request.opaque, midauth_nonce, 18);
2072+
2073+ // build solution
2074+ fail_unless(hip_midauth_puzzle_seed(midauth_nonce, MIDAUTH_DEFAULT_NONCE_LENGTH, tmp_puzzle.puzzle) == 0, NULL);
2075+ tmp_puzzle.initiator_hit = in6addr_any;
2076+ tmp_puzzle.responder_hit = in6addr_any;
2077+ fail_unless(hip_solve_puzzle(&tmp_puzzle, request.K) == 0, NULL);
2078+
2079+ // build parameter
2080+ hip_build_param_challenge_response(hip, &request, tmp_puzzle.solution);
2081+
2082+ fail_unless(hipfw_midauth_verify_challenge(&ctx, midauth_nonce) == 1, NULL);
2083+}
2084+END_TEST
2085+
2086+Suite *firewall_midauth(void)
2087+{
2088+ Suite *s = suite_create("firewall/midauth");
2089+ TCase *tc_midauth = tcase_create("Midauth");
2090+
2091+#ifdef HAVE_TCASE_ADD_EXIT_TEST
2092+ tcase_add_exit_test(tc_midauth, test_hipfw_midauth_add_challenge_NULL_ctx, 1);
2093+ tcase_add_exit_test(tc_midauth, test_hipfw_midauth_add_challenge_NULL_nonce, 1);
2094+ tcase_add_exit_test(tc_midauth, test_hip_challenge_response_opaque_len_NULL, 1);
2095+ tcase_add_exit_test(tc_midauth, test_verify_response_NULL_ctx, 1);
2096+ tcase_add_exit_test(tc_midauth, test_verify_response_NULL_response, 1);
2097+ tcase_add_exit_test(tc_midauth, test_verify_response_NULL_nonce, 1);
2098+ tcase_add_exit_test(tc_midauth, test_hipfw_midauth_verify_challenge_NULL_ctx, 1);
2099+#endif
2100+
2101+ tcase_add_test(tc_midauth, test_hipfw_midauth_add_challenge);
2102+ tcase_add_test(tc_midauth, test_hip_challenge_response_opaque_len);
2103+ tcase_add_test(tc_midauth, test_verify_response_no_match);
2104+ tcase_add_test(tc_midauth, test_verify_response);
2105+ tcase_add_test(tc_midauth, test_hipfw_midauth_verify_challenge_NULL_challenge);
2106+ tcase_add_test(tc_midauth, test_hipfw_midauth_verify_challenge);
2107+
2108+ suite_add_tcase(s, tc_midauth);
2109+
2110+ return s;
2111+}
2112
2113=== added file 'test/firewall/rewrite.c'
2114--- test/firewall/rewrite.c 1970-01-01 00:00:00 +0000
2115+++ test/firewall/rewrite.c 2011-10-25 12:58:23 +0000
2116@@ -0,0 +1,151 @@
2117+/*
2118+ * Copyright (c) 2011 Aalto University and RWTH Aachen University.
2119+ *
2120+ * Permission is hereby granted, free of charge, to any person
2121+ * obtaining a copy of this software and associated documentation
2122+ * files (the "Software"), to deal in the Software without
2123+ * restriction, including without limitation the rights to use,
2124+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
2125+ * copies of the Software, and to permit persons to whom the
2126+ * Software is furnished to do so, subject to the following
2127+ * conditions:
2128+ *
2129+ * The above copyright notice and this permission notice shall be
2130+ * included in all copies or substantial portions of the Software.
2131+ *
2132+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
2133+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
2134+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
2135+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
2136+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
2137+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2138+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2139+ * OTHER DEALINGS IN THE SOFTWARE.
2140+ */
2141+
2142+#define _BSD_SOURCE
2143+
2144+#include <check.h>
2145+#include <stdlib.h>
2146+#include <string.h>
2147+
2148+#include "firewall/firewall_defines.h"
2149+#include "lib/core/common.h"
2150+#include "modules/midauth/hipd/midauth.h"
2151+#include "modules/midauth/lib/midauth_builder.h"
2152+#include "test/mocks.h"
2153+#include "test_suites.h"
2154+
2155+#include "firewall/firewall.c"
2156+
2157+
2158+static const unsigned char tmp_ipq_packet[] = "\xA0\x85\x07\x12\x00\x88\xFF\xFF\x00\x00"
2159+ "\x00\x00\x00\x00\x00\x00\xD3\x98\x81\x4E\x00\x00\x00\x00\x27\x21\x0D"
2160+ "\x00\x00\x00\x00\x00\x02\x00\x00\x00\x65\x74\x68\x31\x00\x00\x00\x00"
2161+ "\x00\x00\x00\x00\x00\x00\x00\x00\x65\x74\x68\x32\x00\x00\x00\x00\x00"
2162+ "\x00\x00\x00\x00\x00\x00\x00\x08\x00\x01\x00\x06\x08\x00\x27\x45\x4D"
2163+ "\x26\x00\x00\x00\x00\x00\x00\x00\x00\x00\xA0\x02\x00\x00\x00\x00\x00"
2164+ "\x00\x45\x00\x02\xA0\x00\x00\x40\x00\x3F\x11\xB3\xEF\xC0\xA8\x01\x0A"
2165+ "\xC0\xA8\x03\x03\x29\x04\x29\x04\x02\x8C\x00\x00\x00\x00\x00\x00\x3B"
2166+ "\x4F\x03\x11\x00\x00\x00\x00\x20\x01\x00\x1B\xD8\xB0\x77\xF0\xC6\x17"
2167+ "\x71\x70\xDE\xD7\xF3\x20\x20\x01\x00\x17\x5D\xF8\xC4\x26\x98\xE5\x5F"
2168+ "\xA2\x28\x6D\x28\x47\x00\x41\x00\x0C\x00\x00\x00\x48\x00\x00\x00\x00"
2169+ "\x2D\x4A\x07\x08\x01\x41\x00\x14\x00\x00\x48\x49\x90\x7D\xD8\x95\x84"
2170+ "\xB3\x8D\xDC\x18\x25\xF9\x65\xE3\x31\x3E\xDD\x01\x42\x00\x1C\x01\x02"
2171+ "\x82\xEC\x42\x00\x00\x00\x00\x00\x5A\x3C\x03\x14\x9A\x0E\x9D\xCA\xF0"
2172+ "\x19\xAD\x2B\xBA\x43\x33\x66\xF8\xB2\x02\x01\x00\xC3\x03\x00\xC0\x7C"
2173+ "\xDA\x02\x1F\xB7\xFE\x85\xBB\xD1\x93\xFD\xB2\xFB\xC0\xB1\xAD\x09\x61"
2174+ "\x1F\x8E\xDD\x8F\x1B\xFC\xC3\x97\xA1\xCE\x4C\x55\x85\xB4\x4A\x8B\x66"
2175+ "\x93\x2A\xDF\x85\xC0\x3A\x84\xA2\x22\x4F\xB3\xF9\x6F\xC5\x54\x23\x9D"
2176+ "\xC2\x03\xEB\xB9\x55\xA4\xF0\x19\xC0\x2B\x4C\xD1\xBF\xC9\x04\xF5\x32"
2177+ "\xAB\x39\xEF\x7B\xF9\xA7\xAB\x5A\xC5\x27\x5E\x21\x83\x48\xB0\x8E\x19"
2178+ "\xB4\x51\x2B\xBA\x79\x00\x62\x70\x48\xF3\x44\xAE\x49\xD4\xC9\x20\x74"
2179+ "\x38\x0D\x11\xCA\xB3\x6F\x03\x47\x9A\x39\xA5\xFB\xC0\x70\xD6\xB5\xB6"
2180+ "\x35\x08\xB4\xB0\x33\x19\xF9\x07\x3C\x82\x7D\x3C\x16\x0C\x74\x9A\x1F"
2181+ "\x9B\xB2\xE6\xB3\xC7\xB3\x08\xE2\x10\x66\x23\x95\xF6\x00\xC7\x57\x8B"
2182+ "\x19\x83\x9E\x6F\xB6\x9D\x6A\x44\x25\xF1\xFD\x45\xFB\xD4\xD9\xE8\xA7"
2183+ "\xD5\xF9\xA7\xA5\xFB\xA3\x23\xD2\xDE\x67\x15\x9C\x6C\xFB\x5B\x08\xAC"
2184+ "\x7F\xC9\xF9\xD7\x00\x02\x41\x00\x02\x00\x01\x00\x00\x02\xC1\x00\x92"
2185+ "\x00\x88\x10\x06\x02\x02\xFF\x05\x03\x01\x00\x01\xD6\xBD\x7C\x86\xC3"
2186+ "\x4A\xA3\x93\x7F\xD9\x82\xBD\x22\xF1\xC7\x4F\x72\x76\x4F\x2F\x68\xF7"
2187+ "\x4F\x9D\xCE\xF3\xAE\xD4\x3B\x13\x5D\xC1\xF7\xF8\x09\x4E\xB4\xCD\x82"
2188+ "\x6F\xF8\xD1\x70\x01\x4E\xC0\x64\x82\xF1\x7E\x21\x54\x62\x73\x08\xEA"
2189+ "\x0A\x66\x1B\xA7\x9A\x4A\xAA\x17\x56\x77\x1D\x4D\x0D\xD2\x19\x92\xA0"
2190+ "\xAC\xF7\x23\x62\xE2\xF0\xFB\x1E\x73\x19\x16\x61\x1B\x85\x02\x42\x4B"
2191+ "\x89\x46\x09\x71\x42\x6F\x40\x8E\x62\x31\xA6\x4F\x17\x45\xF2\x7B\xFA"
2192+ "\xF2\xB6\xC8\x87\x37\x3A\xDF\xBB\x10\xE8\xDA\x97\x31\x6C\x38\xDF\xD0"
2193+ "\x97\x45\x84\x39\x61\x6C\x69\x63\x65\x00\x00\x00\x0F\xFF\x00\x04\x00"
2194+ "\x00\x00\x01\xF0\x41\x00\x14\xE7\x35\x6F\x89\x30\x3E\x1E\xA7\xFB\x93"
2195+ "\x8B\xBE\xD1\x34\x1F\x35\xB8\xE0\x82\x0C\xF1\x01\x00\x81\x05\xA6\xA2"
2196+ "\x75\xEF\xA8\xC3\x9C\x64\x9E\x9A\xDA\xFB\x38\xB4\x05\x8C\x6A\x6E\x5B"
2197+ "\x59\x9F\x11\x5B\xA6\xC0\x05\x42\xA6\x0D\x9C\x62\x17\x0E\x23\xB6\x3B"
2198+ "\x15\xB8\xEC\x6F\xE3\xB6\x6E\x80\x76\x97\xBE\x5B\x5B\x1A\x90\x30\xDF"
2199+ "\x1F\x32\x2C\x4E\x22\x20\x0B\xD4\x2B\x5B\x7C\xEF\x27\xEA\xB9\x80\x27"
2200+ "\xEF\xBC\xB4\xAF\x97\x2A\xD5\x86\xDA\xEE\x2C\xF0\x8B\x45\x00\x10\xE1"
2201+ "\x3A\x95\x35\xAC\x7C\xA8\x88\xC1\x60\xB9\x71\xD3\xE2\x29\xF7\x75\xD0"
2202+ "\x7E\x27\x1B\x21\x43\xAE\xBB\x08\xE1\x6B\x9E\x1E\xB9\x55\x89\xE3\x2B"
2203+ "\x29\x06\x4A\xA2\x90\x98\x38\x00\x00\x00";
2204+static const uint8_t opaque[] = "\x01\x41\x01\x14\x05\x00\x48\x49\x0b"
2205+ "\x02\x42\x02\x15\x06\x08\x49\x50\x0c";
2206+
2207+START_TEST(hipfw_splice_param_correct)
2208+{
2209+ struct hip_fw_context ctx;
2210+ struct hip_common *tmp_msg = NULL;
2211+ const struct hip_tlv_common *param = NULL;
2212+
2213+ mock_ipq = true;
2214+ mock_ipq_pkt_len = ARRAY_SIZE(tmp_ipq_packet);
2215+
2216+ fail_unless(hip_fw_init_context(&ctx, tmp_ipq_packet, 4) == 0, NULL);
2217+
2218+ tmp_msg = hip_msg_alloc();
2219+ hip_build_param_challenge_request(tmp_msg, 0, 0, opaque,
2220+ MIDAUTH_DEFAULT_NONCE_LENGTH);
2221+ param = hip_get_param(tmp_msg, HIP_PARAM_CHALLENGE_REQUEST);
2222+
2223+ fail_unless(hipfw_splice_param(&ctx, param) == true, NULL);
2224+}
2225+END_TEST
2226+
2227+#ifdef HAVE_TCASE_ADD_EXIT_TEST
2228+START_TEST(hipfw_splice_param_NULL_ctx)
2229+{
2230+ struct hip_common *tmp_msg = NULL;
2231+ const struct hip_tlv_common *param = NULL;
2232+
2233+ tmp_msg = hip_msg_alloc();
2234+ hip_build_param_challenge_request(tmp_msg, 0, 0, opaque,
2235+ MIDAUTH_DEFAULT_NONCE_LENGTH);
2236+ param = hip_get_param(tmp_msg, HIP_PARAM_CHALLENGE_REQUEST);
2237+
2238+ fail_unless(hipfw_splice_param(NULL, param) == false, NULL);
2239+}
2240+END_TEST
2241+
2242+START_TEST(hipfw_splice_param_NULL_param)
2243+{
2244+ struct hip_fw_context ctx;
2245+
2246+ mock_ipq = true;
2247+ mock_ipq_pkt_len = ARRAY_SIZE(tmp_ipq_packet);
2248+
2249+ fail_unless(hip_fw_init_context(&ctx, tmp_ipq_packet, 4) == 0, NULL);
2250+ fail_unless(hipfw_splice_param(&ctx, NULL) == false, NULL);
2251+}
2252+END_TEST
2253+#endif
2254+
2255+Suite *firewall_rewrite(void)
2256+{
2257+ Suite *s = suite_create("firewall/rewrite");
2258+ TCase *tc_rewrite = tcase_create("rewrite");
2259+ tcase_add_test(tc_rewrite, hipfw_splice_param_correct);
2260+#ifdef HAVE_TCASE_ADD_EXIT_TEST
2261+ tcase_add_exit_test(tc_rewrite, hipfw_splice_param_NULL_ctx, 1);
2262+ tcase_add_exit_test(tc_rewrite, hipfw_splice_param_NULL_param, 1);
2263+#endif
2264+ suite_add_tcase(s, tc_rewrite);
2265+
2266+ return s;
2267+}
2268
2269=== modified file 'test/firewall/test_suites.h'
2270--- test/firewall/test_suites.h 2011-04-04 16:36:55 +0000
2271+++ test/firewall/test_suites.h 2011-10-25 12:58:23 +0000
2272@@ -32,6 +32,8 @@
2273 Suite *firewall_file_buffer(void);
2274 Suite *firewall_helpers(void);
2275 Suite *firewall_line_parser(void);
2276+Suite *firewall_midauth(void);
2277 Suite *firewall_port_bindings(void);
2278+Suite *firewall_rewrite(void);
2279
2280 #endif /* HIP_TEST_FIREWALL_TEST_SUITES_H */
2281
2282=== modified file 'test/mocks.c'
2283--- test/mocks.c 2011-08-15 14:11:56 +0000
2284+++ test/mocks.c 2011-10-25 12:58:23 +0000
2285@@ -87,6 +87,7 @@
2286 #include <stdlib.h>
2287 #include <string.h>
2288 #include <time.h>
2289+#include <libipq.h>
2290
2291 #include "mocks.h"
2292
2293@@ -189,3 +190,28 @@
2294
2295 return EXIT_SUCCESS;
2296 }
2297+
2298+/*** ipq_get_packet(3) ***/
2299+bool mock_ipq = false;
2300+unsigned int mock_ipq_pkt_len = 0;
2301+
2302+/**
2303+ * ipq_get_packet(3) mock function. Controlled by the ::mock_ipq flag.
2304+ *
2305+ * @param buf contents of the returned ipq_packet_msg_t
2306+ * @return a fully filled ipq_packet_msg_t
2307+ *
2308+ * @note The buffer length is required for this mock function. You can provide
2309+ * it via the ::mock_ipq_pkt_len flag.
2310+ */
2311+ipq_packet_msg_t *ipq_get_packet(const unsigned char *buf)
2312+{
2313+ if (!mock_ipq) {
2314+ ipq_packet_msg_t *(*original)(const unsigned char *) = get_original(ipq_get_packet, "ipq_get_packet");
2315+ return original(buf);
2316+ } else {
2317+ char *tmp = malloc(mock_ipq_pkt_len);
2318+ memcpy(tmp, buf, mock_ipq_pkt_len);
2319+ return (ipq_packet_msg_t *) tmp;
2320+ }
2321+}
2322
2323=== modified file 'test/mocks.h'
2324--- test/mocks.h 2011-04-06 20:27:16 +0000
2325+++ test/mocks.h 2011-10-25 12:58:23 +0000
2326@@ -36,4 +36,7 @@
2327 extern bool mock_system;
2328 extern char *mock_system_last;
2329
2330+extern bool mock_ipq;
2331+extern unsigned int mock_ipq_pkt_len;
2332+
2333 #endif /* HIP_TEST_MOCKS_H */

Subscribers

People subscribed via source and target branches