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
=== modified file 'Makefile.am'
--- Makefile.am 2011-10-17 18:14:10 +0000
+++ Makefile.am 2011-10-25 12:58:23 +0000
@@ -153,6 +153,7 @@
153 firewall/lsi.c \153 firewall/lsi.c \
154 firewall/port_bindings.c \154 firewall/port_bindings.c \
155 firewall/reinject.c \155 firewall/reinject.c \
156 firewall/rewrite.c \
156 firewall/rule_management.c \157 firewall/rule_management.c \
157 firewall/user_ipsec_api.c \158 firewall/user_ipsec_api.c \
158 firewall/user_ipsec_esp.c \159 firewall/user_ipsec_esp.c \
@@ -161,8 +162,7 @@
161 modules/midauth/lib/midauth_builder.c162 modules/midauth/lib/midauth_builder.c
162163
163if HIP_MIDAUTH164if HIP_MIDAUTH
164firewall_hipfw_sources += firewall/midauth.c \165firewall_hipfw_sources += firewall/pisa.c \
165 firewall/pisa.c \
166 firewall/pisa_cert.c166 firewall/pisa_cert.c
167endif167endif
168168
@@ -171,6 +171,7 @@
171# Add all files that need to be excluded here.171# Add all files that need to be excluded here.
172firewall_hipfw_SOURCES = $(firewall_hipfw_sources) \172firewall_hipfw_SOURCES = $(firewall_hipfw_sources) \
173 firewall/conntrack.c \173 firewall/conntrack.c \
174 firewall/midauth.c \
174 firewall/main.c175 firewall/main.c
175176
176lib_core_libhipcore_la_SOURCES = lib/core/builder.c \177lib_core_libhipcore_la_SOURCES = lib/core/builder.c \
@@ -215,7 +216,9 @@
215 test/firewall/file_buffer.c \216 test/firewall/file_buffer.c \
216 test/firewall/helpers.c \217 test/firewall/helpers.c \
217 test/firewall/line_parser.c \218 test/firewall/line_parser.c \
219 test/firewall/midauth.c \
218 test/firewall/port_bindings.c \220 test/firewall/port_bindings.c \
221 test/firewall/rewrite.c \
219 $(firewall_hipfw_sources)222 $(firewall_hipfw_sources)
220223
221test_check_lib_core_SOURCES = test/check_lib_core.c \224test_check_lib_core_SOURCES = test/check_lib_core.c \
@@ -253,7 +256,7 @@
253256
254### dynamic library dependencies ###257### dynamic library dependencies ###
255258
256test_check_firewall_LDFLAGS = -ldl259test_check_firewall_LDFLAGS = -ldl -z muldefs
257260
258dist_sbin_SCRIPTS = tools/hipdnskeyparse/hipdnskeyparse \261dist_sbin_SCRIPTS = tools/hipdnskeyparse/hipdnskeyparse \
259 tools/hipdnsproxy/hipdnsproxy \262 tools/hipdnsproxy/hipdnsproxy \
260263
=== modified file 'firewall/conntrack.c'
--- firewall/conntrack.c 2011-10-19 09:51:41 +0000
+++ firewall/conntrack.c 2011-10-25 12:58:23 +0000
@@ -998,7 +998,7 @@
998 *998 *
999 * @param common the hip packet to be verified999 * @param common the hip packet to be verified
1000 * @param tuple the corresponding connection tuple1000 * @param tuple the corresponding connection tuple
1001 * @return 1 for valid packets, 0 otherwise1001 * @return 0 for valid packets, 1 otherwise
1002 */1002 */
1003static int hip_fw_verify_packet(struct hip_common *const common,1003static int hip_fw_verify_packet(struct hip_common *const common,
1004 const struct tuple *const tuple)1004 const struct tuple *const tuple)
@@ -1017,12 +1017,12 @@
1017 common)) {1017 common)) {
1018 HIP_INFO("Signature verification failed\n");1018 HIP_INFO("Signature verification failed\n");
10191019
1020 return 0;1020 return 1;
1021 }1021 }
10221022
1023 HIP_INFO("Signature successfully verified\n");1023 HIP_INFO("Signature successfully verified\n");
10241024
1025 return 1;1025 return 0;
1026}1026}
10271027
1028/** Verify message authenticity for message types without existing security1028/** Verify message authenticity for message types without existing security
@@ -1030,7 +1030,9 @@
1030 *1030 *
1031 * @param common the hip packet to be verified1031 * @param common the hip packet to be verified
1032 * @param tuple the corresponding connection tuple1032 * @param tuple the corresponding connection tuple
1033 * @return 1 for valid packets, 0 otherwise1033 * @return 0 for valid packets,
1034 * 1 if HOST_ID missing or verification unsuccessful, and
1035 * -1 in case of an error
1034 */1036 */
1035static int hip_fw_verify_and_store_host_id(struct hip_common *const common,1037static int hip_fw_verify_and_store_host_id(struct hip_common *const common,
1036 struct tuple *const tuple)1038 struct tuple *const tuple)
@@ -1040,6 +1042,11 @@
1040 hip_tlv_len len = 0;1042 hip_tlv_len len = 0;
1041 int err = 0;1043 int err = 0;
10421044
1045 HIP_ASSERT(common != NULL);
1046 HIP_ASSERT(tuple != NULL);
1047 HIP_ASSERT(tuple->hip_tuple != NULL);
1048 HIP_ASSERT(tuple->hip_tuple->data != NULL);
1049
1043 HIP_IFEL(!host_id, -1, "Awaiting HOST_ID in control message, but none found\n");1050 HIP_IFEL(!host_id, -1, "Awaiting HOST_ID in control message, but none found\n");
10441051
1045 len = hip_get_param_total_len(host_id);1052 len = hip_get_param_total_len(host_id);
@@ -1077,7 +1084,7 @@
1077 goto out_err;1084 goto out_err;
1078 }1085 }
10791086
1080 err = !hip_fw_verify_packet(common, tuple);1087 err = hip_fw_verify_packet(common, tuple);
10811088
1082out_err:1089out_err:
1083 if (err) {1090 if (err) {
@@ -1170,7 +1177,7 @@
1170 */1177 */
1171static int handle_r1(struct hip_common *const common,1178static int handle_r1(struct hip_common *const common,
1172 struct tuple *const tuple,1179 struct tuple *const tuple,
1173 UNUSED struct hip_fw_context *const ctx)1180 struct hip_fw_context *const ctx)
1174{1181{
1175 if (hip_fw_verify_and_store_host_id(common, tuple)) {1182 if (hip_fw_verify_and_store_host_id(common, tuple)) {
1176 HIP_ERROR("unable to create security state from R1 packet\n");1183 HIP_ERROR("unable to create security state from R1 packet\n");
@@ -1183,6 +1190,11 @@
1183 return 0;1190 return 0;
1184 }1191 }
11851192
1193 if (!hipfw_midauth_add_challenge(ctx, tuple->midauth_nonce)) {
1194 HIP_ERROR("failed to add midauth challenge\n");
1195 return 0;
1196 }
1197
1186 tuple->connection->state = HIP_STATE_R1_SENT;1198 tuple->connection->state = HIP_STATE_R1_SENT;
1187 return 1;1199 return 1;
1188}1200}
@@ -1203,7 +1215,19 @@
1203 struct tuple *const tuple,1215 struct tuple *const tuple,
1204 struct hip_fw_context *const ctx)1216 struct hip_fw_context *const ctx)
1205{1217{
1206 const struct hip_esp_info *const esp_info = hip_get_param(common, HIP_PARAM_ESP_INFO);1218 struct tuple *other_dir = NULL;
1219 const struct hip_esp_info *const esp_info = hip_get_param(common, HIP_PARAM_ESP_INFO);
1220
1221 if (tuple->direction == ORIGINAL_DIR) {
1222 other_dir = &tuple->connection->reply;
1223 } else {
1224 other_dir = &tuple->connection->original;
1225 }
1226
1227 if (!hipfw_midauth_verify_challenge(ctx, other_dir->midauth_nonce)) {
1228 HIP_ERROR("failed to verify midauth challenge\n");
1229 return 0;
1230 }
12071231
1208 if (hip_fw_verify_and_store_host_id(common, tuple)) {1232 if (hip_fw_verify_and_store_host_id(common, tuple)) {
1209 HIP_ERROR("unable to create security state from I2 packet\n");1233 HIP_ERROR("unable to create security state from I2 packet\n");
@@ -1221,6 +1245,11 @@
1221 return 0;1245 return 0;
1222 }1246 }
12231247
1248 if (!hipfw_midauth_add_challenge(ctx, tuple->midauth_nonce)) {
1249 HIP_ERROR("failed to add midauth challenge\n");
1250 return 0;
1251 }
1252
1224 tuple->connection->state = HIP_STATE_I2_SENT;1253 tuple->connection->state = HIP_STATE_I2_SENT;
1225 return 1;1254 return 1;
1226}1255}
@@ -1242,9 +1271,21 @@
1242 struct tuple *const tuple,1271 struct tuple *const tuple,
1243 const struct hip_fw_context *const ctx)1272 const struct hip_fw_context *const ctx)
1244{1273{
1245 const struct hip_esp_info *const esp_info = hip_get_param(common, HIP_PARAM_ESP_INFO);1274 const struct tuple *other_dir = NULL;
12461275 const struct hip_esp_info *const esp_info = hip_get_param(common, HIP_PARAM_ESP_INFO);
1247 if (!hip_fw_verify_packet(common, tuple)) {1276
1277 if (tuple->direction == ORIGINAL_DIR) {
1278 other_dir = &tuple->connection->reply;
1279 } else {
1280 other_dir = &tuple->connection->original;
1281 }
1282
1283 if (!hipfw_midauth_verify_challenge(ctx, other_dir->midauth_nonce)) {
1284 HIP_ERROR("failed to verify midauth challenge\n");
1285 return 0;
1286 }
1287
1288 if (hip_fw_verify_packet(common, tuple)) {
1248 HIP_ERROR("failed to verify R2 packet\n");1289 HIP_ERROR("failed to verify R2 packet\n");
1249 return 0;1290 return 0;
1250 }1291 }
@@ -1421,9 +1462,6 @@
14211462
1422 remove_connection(tuple->connection);1463 remove_connection(tuple->connection);
14231464
1424 /** FIXME the firewall should not care about locator for esp tracking
1425 *
1426 * NOTE: modify this regardingly! */
1427 if (insert_connection_from_update(common, ctx, esp_info)) {1465 if (insert_connection_from_update(common, ctx, esp_info)) {
1428 HIP_ERROR("connection insertion failed\n");1466 HIP_ERROR("connection insertion failed\n");
14291467
@@ -1502,11 +1540,12 @@
1502 struct tuple *tuple,1540 struct tuple *tuple,
1503 struct hip_fw_context *const ctx)1541 struct hip_fw_context *const ctx)
1504{1542{
1505 const struct hip_esp_info *esp_info = NULL;1543 const struct hip_esp_info *esp_info = NULL;
1506 const struct hip_locator *locator = NULL;1544 const struct hip_locator *locator = NULL;
1507 const struct hip_seq *seq = NULL;1545 const struct hip_seq *seq = NULL;
1508 const struct hip_ack *ack = NULL;1546 const struct hip_ack *ack = NULL;
1509 enum hip_state state = HIP_STATE_NONE;1547 struct tuple *other_dir = NULL;
1548 enum hip_state state = HIP_STATE_NONE;
15101549
1511 /* classify UPDATE message */1550 /* classify UPDATE message */
1512 esp_info = hip_get_param(common, HIP_PARAM_ESP_INFO);1551 esp_info = hip_get_param(common, HIP_PARAM_ESP_INFO);
@@ -1526,14 +1565,26 @@
1526 tuple = get_tuple_by_hits(&common->hits, &common->hitr);1565 tuple = get_tuple_by_hits(&common->hits, &common->hitr);
1527 }1566 }
15281567
1568 if (!tuple || !hipfw_midauth_add_challenge(ctx, tuple->midauth_nonce)) {
1569 HIP_ERROR("failed to add midauth challenge\n");
1570 return 0;
1571 }
1572
1529 state = HIP_STATE_U1_SENT;1573 state = HIP_STATE_U1_SENT;
1530 } else if (esp_info && seq && ack) {1574 } else if (esp_info && seq && ack) {
1531 if (!tuple) {1575 if (!tuple) {
1532 HIP_ERROR("Insufficient stored state to process UPDATE\n");1576 HIP_ERROR("Insufficient stored state to process UPDATE\n");
1533 return 0;1577 return 0;
1534 }1578 }
15351579 other_dir = tuple->direction == ORIGINAL_DIR ? &tuple->connection->reply
1536 if (!hip_fw_verify_packet(common, tuple)) {1580 : &tuple->connection->original;
1581
1582 if (!hipfw_midauth_verify_challenge(ctx, other_dir->midauth_nonce)) {
1583 HIP_ERROR("failed to verify midauth challenge\n");
1584 return 0;
1585 }
1586
1587 if (hip_fw_verify_and_store_host_id(common, tuple)) {
1537 HIP_ERROR("failed to verify UPDATE packet\n");1588 HIP_ERROR("failed to verify UPDATE packet\n");
1538 return 0;1589 return 0;
1539 }1590 }
@@ -1543,14 +1594,27 @@
1543 return 0;1594 return 0;
1544 }1595 }
15451596
1597 if (!tuple || !hipfw_midauth_add_challenge(ctx, tuple->midauth_nonce)) {
1598 HIP_ERROR("failed to add midauth challenge\n");
1599 return 0;
1600 }
1601
1546 state = HIP_STATE_U2_SENT;1602 state = HIP_STATE_U2_SENT;
1547 } else if (ack) {1603 } else if (ack) {
1548 if (!tuple) {1604 if (!tuple) {
1549 HIP_ERROR("Insufficient stored state to process UPDATE\n");1605 HIP_ERROR("Insufficient stored state to process UPDATE\n");
1550 return 0;1606 return 0;
1551 }1607 }
15521608 other_dir = tuple->direction == ORIGINAL_DIR ? &tuple->connection->reply
1553 if (!hip_fw_verify_packet(common, tuple)) {1609 : &tuple->connection->original;
1610
1611 if (!other_dir ||
1612 !hipfw_midauth_verify_challenge(ctx, other_dir->midauth_nonce)) {
1613 HIP_ERROR("failed to verify midauth challenge\n");
1614 return 0;
1615 }
1616
1617 if (hip_fw_verify_and_store_host_id(common, tuple)) {
1554 HIP_ERROR("failed to verify UPDATE packet\n");1618 HIP_ERROR("failed to verify UPDATE packet\n");
1555 return 0;1619 return 0;
1556 }1620 }
@@ -1592,7 +1656,7 @@
1592#endif1656#endif
1593 HIP_IFEL(!tuple, 1, "no connection state for CLOSE\n");1657 HIP_IFEL(!tuple, 1, "no connection state for CLOSE\n");
15941658
1595 HIP_IFEL(!hip_fw_verify_packet(common, tuple), 0,1659 HIP_IFEL(hip_fw_verify_packet(common, tuple), 0,
1596 "failed to verify CLOSE packet\n");1660 "failed to verify CLOSE packet\n");
15971661
1598 tuple->connection->state = HIP_STATE_CLOSING;1662 tuple->connection->state = HIP_STATE_CLOSING;
@@ -1628,7 +1692,7 @@
1628#endif1692#endif
1629 HIP_IFEL(!tuple, 1, "no connection state for CLOSE_ACK\n");1693 HIP_IFEL(!tuple, 1, "no connection state for CLOSE_ACK\n");
16301694
1631 HIP_IFEL(!hip_fw_verify_packet(common, tuple), 0,1695 HIP_IFEL(hip_fw_verify_packet(common, tuple), 0,
1632 "failed to verify CLOSE_ACK packet\n");1696 "failed to verify CLOSE_ACK packet\n");
16331697
1634 remove_connection(tuple->connection);1698 remove_connection(tuple->connection);
16351699
=== modified file 'firewall/firewall.c'
--- firewall/firewall.c 2011-08-16 07:49:25 +0000
+++ firewall/firewall.c 2011-10-25 12:58:23 +0000
@@ -76,12 +76,13 @@
76#include "lib/core/prefix.h"76#include "lib/core/prefix.h"
77#include "lib/core/util.h"77#include "lib/core/util.h"
78#include "hipd/hipd.h"78#include "hipd/hipd.h"
79#include "config.h"
80#include "cache.h"79#include "cache.h"
81#include "common_types.h"80#include "common_types.h"
81#include "config.h"
82#include "conntrack.h"82#include "conntrack.h"
83#include "esp_prot_api.h"83#include "esp_prot_api.h"
84#include "esp_prot_conntrack.h"84#include "esp_prot_conntrack.h"
85#include "firewall.h"
85#include "firewall_control.h"86#include "firewall_control.h"
86#include "firewall_defines.h"87#include "firewall_defines.h"
87#include "helpers.h"88#include "helpers.h"
@@ -90,9 +91,9 @@
90#include "pisa.h"91#include "pisa.h"
91#include "port_bindings.h"92#include "port_bindings.h"
92#include "reinject.h"93#include "reinject.h"
94#include "rewrite.h"
93#include "rule_management.h"95#include "rule_management.h"
94#include "user_ipsec_api.h"96#include "user_ipsec_api.h"
95#include "firewall.h"
9697
9798
98/* location of the lock file */99/* location of the lock file */
@@ -134,9 +135,6 @@
134int esp_relay = 0;135int esp_relay = 0;
135int hip_esp_protection = 0;136int hip_esp_protection = 0;
136int esp_speedup = 0; /**< Enable esp speedup via dynamic iptables usage (-u option). */137int esp_speedup = 0; /**< Enable esp speedup via dynamic iptables usage (-u option). */
137#ifdef CONFIG_HIP_MIDAUTH
138int use_midauth = 0;
139#endif
140138
141/** Use this to send and receive responses to hipd. Notice that139/** Use this to send and receive responses to hipd. Notice that
142 * firewall_control.c has a separate socket for receiving asynchronous140 * firewall_control.c has a separate socket for receiving asynchronous
@@ -485,9 +483,7 @@
485 HIP_IFEL(hip_fw_init_esp_prot(), -1, "failed to load extension\n");483 HIP_IFEL(hip_fw_init_esp_prot(), -1, "failed to load extension\n");
486 HIP_IFEL(hip_fw_init_esp_prot_conntrack(), -1, "failed to load extension\n");484 HIP_IFEL(hip_fw_init_esp_prot_conntrack(), -1, "failed to load extension\n");
487485
488#ifdef CONFIG_HIP_MIDAUTH
489 midauth_init();486 midauth_init();
490#endif
491487
492 // Initializing local port cache database488 // Initializing local port cache database
493 hip_port_bindings_init(true);489 hip_port_bindings_init(true);
@@ -1147,13 +1143,6 @@
1147{1143{
1148 HIP_DEBUG("\n");1144 HIP_DEBUG("\n");
11491145
1150#ifdef CONFIG_HIP_MIDAUTH
1151 if (use_midauth) {
1152 if (midauth_filter_hip(ctx) == NF_DROP) {
1153 return NF_DROP;
1154 }
1155 }
1156#endif
1157 // for now forward and output are handled symmetrically1146 // for now forward and output are handled symmetrically
1158 return hip_fw_handle_hip_output(ctx);1147 return hip_fw_handle_hip_output(ctx);
1159}1148}
@@ -1530,22 +1519,6 @@
1530}1519}
15311520
1532/**1521/**
1533 * Set an accept verdict for a modified packet
1534 *
1535 * @param handle ipqueue file handle
1536 * @param packet_id ipqueue packet id
1537 * @param len length of buf
1538 * @param buf the packet to be accepted
1539 *
1540 */
1541static void allow_modified_packet(struct ipq_handle *handle, unsigned long packet_id,
1542 size_t len, unsigned char *buf)
1543{
1544 ipq_set_verdict(handle, packet_id, NF_ACCEPT, len, buf);
1545 HIP_DEBUG("Packet accepted with modifications\n\n");
1546}
1547
1548/**
1549 * Allow a packet to pass1522 * Allow a packet to pass
1550 *1523 *
1551 * @param handle the handle for the packets.1524 * @param handle the handle for the packets.
@@ -1639,9 +1612,7 @@
1639 allow_packet(hndl, ctx->ipq_packet->packet_id);1612 allow_packet(hndl, ctx->ipq_packet->packet_id);
1640 } else {1613 } else {
1641 HIP_DEBUG("=== Verdict: allow modified packet ===\n");1614 HIP_DEBUG("=== Verdict: allow modified packet ===\n");
1642 allow_modified_packet(hndl, ctx->ipq_packet->packet_id,1615 allow_modified_packet(hndl, ctx);
1643 ctx->ipq_packet->data_len,
1644 ctx->ipq_packet->payload);
1645 }1616 }
1646 } else {1617 } else {
1647 HIP_DEBUG("=== Verdict: drop packet ===\n");1618 HIP_DEBUG("=== Verdict: drop packet ===\n");
@@ -1928,7 +1899,7 @@
1928 continue;1899 continue;
1929 }1900 }
19301901
1931#ifdef CONFIG_HIP_MIDAUTH1902#ifdef CONFIG_HIP_PISA
1932 if (use_midauth) {1903 if (use_midauth) {
1933 pisa_check_for_random_update();1904 pisa_check_for_random_update();
1934 }1905 }
19351906
=== modified file 'firewall/firewall.h'
--- firewall/firewall.h 2011-04-05 16:44:22 +0000
+++ firewall/firewall.h 2011-10-25 12:58:23 +0000
@@ -43,7 +43,6 @@
43extern int hip_lsi_support;43extern int hip_lsi_support;
44extern int esp_relay;44extern int esp_relay;
45extern int hip_esp_protection;45extern int hip_esp_protection;
46extern int use_midauth;
47extern int hip_fw_sock;46extern int hip_fw_sock;
48extern int system_based_opp_mode;47extern int system_based_opp_mode;
49extern int esp_speedup;48extern int esp_speedup;
5049
=== modified file 'firewall/firewall_defines.h'
--- firewall/firewall_defines.h 2011-09-07 13:33:42 +0000
+++ firewall/firewall_defines.h 2011-10-25 12:58:23 +0000
@@ -50,6 +50,12 @@
50 FW_PROTO_NUM50 FW_PROTO_NUM
51};51};
5252
53/**
54 * @note When adding new members, check if hip_fw_context_enable_write() needs
55 * to be updated as well.
56 * @see hip_fw_context_enable_write()
57 * @see hip_fw_context_enable_write_inplace()
58 */
53struct hip_fw_context {59struct hip_fw_context {
54 // queued packet60 // queued packet
55 ipq_packet_msg_t *ipq_packet;61 ipq_packet_msg_t *ipq_packet;
@@ -74,6 +80,8 @@
74 int modified;80 int modified;
75};81};
7682
83#include "midauth.h"
84
77/********** State table structures **************/85/********** State table structures **************/
7886
79struct esp_address {87struct esp_address {
@@ -137,6 +145,7 @@
137 int esp_relay;145 int esp_relay;
138 struct in6_addr esp_relay_daddr;146 struct in6_addr esp_relay_daddr;
139 in_port_t esp_relay_dport;147 in_port_t esp_relay_dport;
148 uint8_t midauth_nonce[MIDAUTH_DEFAULT_NONCE_LENGTH];
140};149};
141150
142struct connection {151struct connection {
@@ -150,9 +159,7 @@
150 /* members needed for ESP protection extension */159 /* members needed for ESP protection extension */
151 int num_esp_prot_tfms;160 int num_esp_prot_tfms;
152 uint8_t esp_prot_tfms[MAX_NUM_TRANSFORMS];161 uint8_t esp_prot_tfms[MAX_NUM_TRANSFORMS];
153#ifdef CONFIG_HIP_MIDAUTH162 int pisa_state;
154 int pisa_state;
155#endif
156};163};
157164
158#endif /* HIP_FIREWALL_FIREWALL_DEFINES_H */165#endif /* HIP_FIREWALL_FIREWALL_DEFINES_H */
159166
=== modified file 'firewall/main.c'
--- firewall/main.c 2011-06-22 13:25:54 +0000
+++ firewall/main.c 2011-10-25 12:58:23 +0000
@@ -45,6 +45,7 @@
45#include "lib/core/util.h"45#include "lib/core/util.h"
46#include "firewall.h"46#include "firewall.h"
47#include "conntrack.h"47#include "conntrack.h"
48#include "midauth.h"
4849
4950
50/**51/**
@@ -53,10 +54,7 @@
53static void hipfw_usage(void)54static void hipfw_usage(void)
54{55{
55 puts("HIP Firewall");56 puts("HIP Firewall");
56 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]");57 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]");
57#ifdef CONFIG_HIP_MIDAUTH
58 puts(" [-m]");
59#endif
60 puts("");58 puts("");
61 puts(" -f file_name = is a path to a file containing firewall filtering rules");59 puts(" -f file_name = is a path to a file containing firewall filtering rules");
62 puts(" -V = print version information and exit");60 puts(" -V = print version information and exit");
@@ -71,14 +69,11 @@
71 puts(" -I = as -i, also allow fallback to kernel ipsec when exiting hipfw");69 puts(" -I = as -i, also allow fallback to kernel ipsec when exiting hipfw");
72 puts(" -e = use esp protection extension (also sets -i)");70 puts(" -e = use esp protection extension (also sets -i)");
73 puts(" -l = activate lsi support");71 puts(" -l = activate lsi support");
72 puts(" -m = middlebox authentication");
74 puts(" -p = run with lowered privileges. iptables rules will not be flushed on exit");73 puts(" -p = run with lowered privileges. iptables rules will not be flushed on exit");
75 puts(" -t <seconds> = set timeout interval to <seconds>. Disable if <seconds> = 0");74 puts(" -t <seconds> = set timeout interval to <seconds>. Disable if <seconds> = 0");
76 puts(" -u = attempt to speed up esp traffic using iptables rules");75 puts(" -u = attempt to speed up esp traffic using iptables rules");
77 puts(" -h = print this help");76 puts(" -h = print this help");
78#ifdef CONFIG_HIP_MIDAUTH
79 puts(" -m = middlebox authentication");
80 puts(" -w = IP address of web-based authentication server");
81#endif
82 puts("");77 puts("");
83}78}
8479
@@ -153,11 +148,9 @@
153 hip_lsi_support = 1;148 hip_lsi_support = 1;
154 break;149 break;
155 case 'm':150 case 'm':
156#ifdef CONFIG_HIP_MIDAUTH
157 filter_traffic = 1;151 filter_traffic = 1;
158 use_midauth = 1;152 use_midauth = 1;
159 break;153 break;
160#endif
161 case 'p':154 case 'p':
162 limit_capabilities = 1;155 limit_capabilities = 1;
163 break;156 break;
164157
=== modified file 'firewall/midauth.c'
--- firewall/midauth.c 2011-08-15 14:11:56 +0000
+++ firewall/midauth.c 2011-10-25 12:58:23 +0000
@@ -38,416 +38,245 @@
3838
39#define _BSD_SOURCE39#define _BSD_SOURCE
4040
41#include <stdint.h>41#include <openssl/rand.h>
42#include <stdbool.h>
42#include <string.h>43#include <string.h>
43#include <arpa/inet.h>
44#include <netinet/ip.h>
45#include <sys/socket.h>
46#include <sys/types.h>
47#include <linux/netfilter.h>
4844
49#include "lib/core/builder.h"45#include "lib/core/builder.h"
50#include "lib/core/debug.h"46#include "lib/core/debug.h"
51#include "lib/core/ife.h"
52#include "lib/core/protodefs.h"
53#include "lib/core/solve.h"47#include "lib/core/solve.h"
54#include "lib/tool/checksum.h"48#include "modules/midauth/hipd/midauth.h"
49#include "modules/midauth/lib/midauth_builder.h"
55#include "firewall_defines.h"50#include "firewall_defines.h"
56#include "pisa.h"51#include "rewrite.h"
57#include "midauth.h"52#include "midauth.h"
5853
5954
60static struct midauth_handlers handlers;55// static configuration
6156static const bool ignore_missing_challenge_request = false;
62/**57static const bool ignore_missing_challenge_response = false;
63 * Changes IPv4 header to match new length and updates the checksum.58static const bool ignore_wrong_challenge_solution = false;
64 *59static const bool ignore_malformed_update = false;
65 * @param ip a pointer to the IPv4 header60static const bool notify_failed_challenge = true;
66 * @param len new payload length61
67 */62static const uint8_t DEFAULT_DIFFICULTY = 1;
68static void update_ipv4_header(struct iphdr *ip, int len)63
69{64// runtime configuration
70 unsigned short *w = (unsigned short *) ip;65bool use_midauth = false;
71 int hdrlen, checksum = 0;66
7267/**
73 ip->tot_len = htons(len);68 * Initialize the midauth extension for the firewall.
74 ip->check = 0;
75
76 for (hdrlen = ip->ihl * 4, checksum = 0; hdrlen > 1; hdrlen -= 2) {
77 checksum += *w++;
78 }
79 if (hdrlen == 1) {
80 unsigned short padding = 0;
81 *(unsigned char *) (&padding) = *(unsigned char *) w;
82 checksum += padding;
83 }
84
85 checksum = (checksum >> 16) + (checksum & 0xffff);
86 checksum += checksum >> 16;
87
88 ip->check = ~checksum;
89}
90
91/**
92 * Changes IPv6 header to match new length.
93 *
94 * @param ip a pointer to the IPv6 header
95 * @param len new IPv6 packet length
96 */
97static void update_ipv6_header(struct ip6_hdr *ip, int len)
98{
99 ip->ip6_ctlun.ip6_un1.ip6_un1_plen = htons(len - sizeof(struct ip6_hdr));
100}
101
102#define CHECKSUM_CARRY(x) \
103 (x = (x >> 16) + (x & 0xffff), (~(x + (x >> 16)) & 0xffff))
104
105/**
106 * Changes UDP header for IPv4 to match new content and updates the checksum.
107 *
108 * @param ip a pointer to the IPv4 header, not the UDP header
109 * @param len total length of the IPv4 packet
110 */
111static void update_udp_header(struct iphdr *ip, int len)
112{
113 unsigned long sum;
114 uint16_t *w = (uint16_t *) ((unsigned char *) ip + (ip->ihl * 4));
115 uint16_t protocol = ntohs(IPPROTO_UDP);
116 int i;
117 struct udphdr *udp = (struct udphdr *) w;
118
119 len -= ip->ihl * 4;
120
121 udp->check = 0;
122 udp->len = htons(len);
123
124 /* UDP header and data */
125 sum = 0;
126 while (len > 0) {
127 sum += *w++;
128 len -= 2;
129 }
130 if (len == 1) {
131 unsigned short padding = 0;
132 *(unsigned char *) (&padding) = *(unsigned char *) w;
133 sum += padding;
134 }
135
136 /* add UDP pseudoheader */
137 w = (uint16_t *) &ip->saddr;
138 for (i = 0; i < 4; w++, i++) {
139 sum += *w;
140 }
141 sum += protocol;
142 sum += udp->len;
143
144 /* set the checksum */
145 udp->check = CHECKSUM_CARRY(sum);
146}
147
148/**
149 * Calculate the new checksum for the HIP packet in IPv4. Note that UDP
150 * encapsulated HIP packets don't have a checksum. Therefore don't call this
151 * function for them.
152 *
153 * @param ip the modified IP packet
154 */
155static void update_hip_checksum_ipv4(struct iphdr *ip)
156{
157 struct sockaddr_in src = { 0 }, dst = { 0 };
158 struct hip_common *msg = (struct hip_common *) ((char *) ip +
159 (ip->ihl * 4));
160
161 src.sin_family = AF_INET;
162 memcpy(&src.sin_addr, &ip->saddr, sizeof(uint32_t));
163
164 dst.sin_family = AF_INET;
165 memcpy(&dst.sin_addr, &ip->daddr, sizeof(uint32_t));
166
167 hip_zero_msg_checksum(msg);
168 msg->checksum = hip_checksum_packet((char *) msg,
169 (struct sockaddr *) &src,
170 (struct sockaddr *) &dst);
171}
172
173/**
174 * Calculate the new checksum for the HIP packet in IPv6.
175 *
176 * @param ip the modified IP packet
177 */
178static void update_hip_checksum_ipv6(struct ip6_hdr *ip)
179{
180 struct sockaddr_in6 src = { 0 }, dst = { 0 };
181 struct hip_common *msg = (struct hip_common *) ((char *) ip +
182 sizeof(struct ip6_hdr));
183
184 src.sin6_family = AF_INET6;
185 memcpy(&src.sin6_addr, &ip->ip6_src, sizeof(struct in6_addr));
186
187 dst.sin6_family = AF_INET6;
188 memcpy(&dst.sin6_addr, &ip->ip6_dst, sizeof(struct in6_addr));
189
190 hip_zero_msg_checksum(msg);
191 msg->checksum = hip_checksum_packet((char *) msg,
192 (struct sockaddr *) &src,
193 (struct sockaddr *) &dst);
194}
195
196/**
197 * Take care of adapting all headers in front of the HIP payload to the new
198 * content.
199 *
200 * @param ctx context of the modified midauth packet
201 */
202static void midauth_update_all_headers(struct hip_fw_context *ctx)
203{
204 struct iphdr *ipv4 = NULL;
205 struct ip6_hdr *ipv6 = NULL;
206 size_t len = 0;
207
208 len = hip_get_msg_total_len(ctx->transport_hdr.hip);
209
210 switch (ctx->ip_version) {
211 case 4:
212 ipv4 = (struct iphdr *) ctx->ipq_packet->payload;
213 len += ipv4->ihl * 4;
214 if (ipv4->protocol == IPPROTO_UDP) {
215 len += sizeof(struct udphdr) + HIP_UDP_ZERO_BYTES_LEN;
216 update_udp_header(ipv4, len);
217 } else {
218 update_hip_checksum_ipv4(ipv4);
219 }
220 update_ipv4_header(ipv4, len);
221 break;
222 case 6:
223 ipv6 = (struct ip6_hdr *) ctx->ipq_packet->payload;
224 len += sizeof(struct ip6_hdr);
225 update_hip_checksum_ipv6(ipv6);
226 update_ipv6_header(ipv6, len);
227 break;
228 default:
229 HIP_ERROR("Unknown IP version. %i, expected 4 or 6.\n",
230 ctx->ip_version);
231 break;
232 }
233
234 ctx->ipq_packet->data_len = len;
235}
236
237/**
238 * Verify that the challenge response in a packet is valid
239 *
240 * @param solution challenge response parameter
241 * @param initiator_hit HIT of the initiator
242 * @param responder_hit HIT of the receiver
243 * @return 0 on success, <0 otherwise
244 */
245int midauth_verify_challenge_response(const struct hip_challenge_response *const solution,
246 const hip_hit_t initiator_hit,
247 const hip_hit_t responder_hit)
248{
249 int err = 0;
250 struct puzzle_hash_input puzzle_input;
251 uint8_t digest[HIP_AH_SHA_LEN];
252
253 HIP_IFEL(hip_build_digest(HIP_DIGEST_SHA1, solution->opaque, 24, digest) < 0,
254 -1, "Building of SHA1 Random seed I failed\n");
255
256 memcpy(puzzle_input.puzzle,
257 &digest[HIP_AH_SHA_LEN - PUZZLE_LENGTH],
258 PUZZLE_LENGTH);
259 puzzle_input.initiator_hit = initiator_hit;
260 puzzle_input.responder_hit = responder_hit;
261 memcpy(puzzle_input.solution, solution->J, PUZZLE_LENGTH);
262
263 HIP_IFEL(hip_verify_puzzle_solution(&puzzle_input, solution->K),
264 -1, "Solution is wrong\n");
265
266out_err:
267 return err;
268}
269
270/**
271 * Move the last HIP parameter to the correct position according to its
272 * parameter type. Will probably break the packet if something is moved in
273 * front of a signature.
274 *
275 * @param hip the HIP packet
276 * @return 0 on success
277 */
278static int midauth_relocate_last_hip_parameter(struct hip_common *hip)
279{
280 int err = 0, len, total_len, offset;
281 char buffer[HIP_MAX_PACKET], *ptr = (char *) hip;
282 struct hip_tlv_common *i = NULL, *last = NULL;
283 hip_tlv type;
284
285 while ((i = hip_get_next_param_readwrite(hip, i))) {
286 last = i;
287 }
288
289 HIP_IFEL(last == NULL, -1, "Trying to relocate in an empty packet!\n");
290
291 total_len = hip_get_msg_total_len(hip);
292 len = hip_get_param_total_len(last);
293 type = hip_get_param_type(last);
294
295 HIP_IFEL(len > (int) sizeof(buffer), -1,
296 "Last parameter's length exceeds HIP_MAX_PACKET\n");
297
298 /* @todo check for signature parameter to avoid broken packets */
299
300 memcpy(buffer, last, len);
301 i = NULL;
302
303 while ((i = hip_get_next_param_readwrite(hip, i))) {
304 if (hip_get_param_type(i) > type) {
305 offset = (char *) i - (char *) hip;
306
307 memmove(ptr + offset + len, ptr + offset,
308 total_len - offset - len);
309 memcpy(ptr + offset, buffer, len);
310 break;
311 }
312 }
313
314out_err:
315 return err;
316}
317
318/**
319 * Creates a challenge request and adds it to a forwarded HIP
320 * packet.
321 *
322 * @param ctx connection context of the modified packet
323 * @param val_K puzzle difficulty
324 * @param ltime lifetime of the challenge in s
325 * @param opaque contents of the opaque data field
326 * @param opaque_len length of the opaque data field
327 * @return 0 on success, <0 otherwise
328 */
329int midauth_add_challenge_request(struct hip_fw_context *ctx, uint8_t val_K,
330 uint8_t ltime,
331 uint8_t *opaque,
332 uint8_t opaque_len)
333{
334 struct hip_common *hip = ctx->transport_hdr.hip;
335 int err = 0;
336
337 ctx->modified = 1;
338
339 HIP_IFEL(hip_build_param_challenge_request(hip, val_K, ltime,
340 opaque, opaque_len),
341 -1, "Failed to build challenge_request parameter\n");
342 HIP_IFEL(midauth_relocate_last_hip_parameter(hip), -1,
343 "Failed to relocate new challenge_request parameter\n");
344
345out_err:
346 return err;
347}
348
349int midauth_handler_accept(UNUSED struct hip_fw_context *ctx)
350{
351 return NF_ACCEPT;
352}
353
354/**
355 * Drops a packet. Used in midauth_handlers as a default handler.
356 *
357 * @param ctx context of the packet
358 * @return NF_DROP
359 */
360static int midauth_handler_drop(UNUSED struct hip_fw_context *ctx)
361{
362 return NF_DROP;
363}
364
365/**
366 * Distinguish the different UPDATE packets.
367 *
368 * @param ctx context of the modified packet
369 * @return the verdict, either NF_ACCEPT or NF_DROP
370 */
371static midauth_handler filter_midauth_update(const struct hip_fw_context *ctx)
372{
373 if (hip_get_param(ctx->transport_hdr.hip, HIP_PARAM_LOCATOR)) {
374 return handlers.u1;
375 }
376 if (hip_get_param(ctx->transport_hdr.hip, HIP_PARAM_ECHO_REQUEST)) {
377 return handlers.u2;
378 }
379 if (hip_get_param(ctx->transport_hdr.hip, HIP_PARAM_ECHO_RESPONSE)) {
380 return handlers.u3;
381 }
382
383 HIP_ERROR("Unknown UPDATE format, rejecting the request!\n");
384 return midauth_handler_drop;
385}
386
387/**
388 * Packet handler dispatcher function. Classifies packets based on
389 * their type and calls the appropriate type-specific handler functions.
390 *
391 * @param ctx HIP connection context
392 * @return the verdict, either NF_ACCEPT or NF_DROP
393 */
394int midauth_filter_hip(struct hip_fw_context *ctx)
395{
396 int verdict = NF_ACCEPT;
397 midauth_handler h = NULL;
398 midauth_handler h_default = midauth_handler_accept;
399 /* @todo change this default value to midauth_handler_drop to
400 * disallow unknown message types */
401
402 switch (ctx->transport_hdr.hip->type_hdr) {
403 case HIP_I1:
404 h = handlers.i1;
405 break;
406 case HIP_R1:
407 h = handlers.r1;
408 break;
409 case HIP_I2:
410 h = handlers.i2;
411 break;
412 case HIP_R2:
413 h = handlers.r2;
414 break;
415 case HIP_UPDATE:
416 h = filter_midauth_update(ctx);
417 break;
418 case HIP_CLOSE:
419 h = handlers.close;
420 break;
421 case HIP_CLOSE_ACK:
422 h = handlers.close_ack;
423 break;
424 default:
425 HIP_DEBUG("filtering default message type\n");
426 break;
427 }
428
429 if (!h) {
430 h = h_default;
431 }
432 verdict = h(ctx);
433
434 /* do not change packet when it is dropped */
435 if (verdict != NF_ACCEPT) {
436 ctx->modified = 0;
437 }
438
439 /* if packet was modified correct every necessary part */
440 if (ctx->modified != 0) {
441 midauth_update_all_headers(ctx);
442 }
443
444 return verdict;
445}
446
447/**
448 * Call the initializer functions
449 */69 */
450void midauth_init(void)70void midauth_init(void)
451{71{
452 pisa_init(&handlers);72 HIP_DEBUG("== midauth enabled ==\n");
73}
74
75/**
76 * Get the lifetime of a midauth challenge.
77 *
78 * @param difficulty The difficulty of the puzzle.
79 * @return The lifetime of the challenge.
80 *
81 * @todo Lifetime should depend on difficulty.
82 */
83static inline uint8_t lifetime(UNUSED const uint8_t difficulty)
84{
85 return 2;
86}
87
88/**
89 * Add a CHALLENGE_REQUEST parameter to a HIP packet passing through the
90 * firewall.
91 *
92 * @param ctx The packet context.
93 * @param[out] midauth_nonce The nonce added by the firewall for this handshake.
94 * @return 1 on success, 0 otherwise
95 */
96int hipfw_midauth_add_challenge(struct hip_fw_context *const ctx,
97 uint8_t midauth_nonce[MIDAUTH_DEFAULT_NONCE_LENGTH])
98{
99 struct hip_challenge_request request;
100 static const size_t min_length = sizeof(request) -
101 sizeof(request.tlv) -
102 sizeof(request.opaque);
103
104 if (use_midauth) {
105 HIP_ASSERT(midauth_nonce);
106 HIP_ASSERT(ctx);
107 HIP_ASSERT(ctx->packet_type == HIP_PACKET);
108
109 /* note: the length cannot be calculated with calc_param_len() */
110 hip_set_param_contents_len(&request.tlv,
111 min_length + MIDAUTH_DEFAULT_NONCE_LENGTH);
112 hip_set_param_type(&request.tlv, HIP_PARAM_CHALLENGE_REQUEST);
113
114 request.K = DEFAULT_DIFFICULTY;
115 request.lifetime = lifetime(DEFAULT_DIFFICULTY);
116
117 if (!RAND_bytes(request.opaque, MIDAUTH_DEFAULT_NONCE_LENGTH)) {
118 HIP_ERROR("Failed to generate CHALLENGE_REQUEST nonce\n");
119 return ignore_missing_challenge_request;
120 }
121
122 // IP (and UDP, if needed) frames will be updated upon send
123 // Implicitly calls hip_fw_context_enable_write() if needed
124 if (!hipfw_splice_param(ctx, &request.tlv)) {
125 HIP_ERROR("Failed to splice CHALLENGE_REQUEST into existing packet\n");
126
127 // fatality depends on current settings
128 return ignore_missing_challenge_request;
129 }
130
131 /* store nonce per-connection per-peer */
132 memcpy(midauth_nonce, request.opaque, MIDAUTH_DEFAULT_NONCE_LENGTH);
133 }
134
135 return 1;
136}
137
138/**
139 * Getter for the length of the opaque field in a CHALLENGE_REPSONSE parameter.
140 *
141 * @param response The CHALLENGE_REPSONSE parameter.
142 * @return The length of the opaque value.
143 */
144static uint8_t hip_challenge_response_opaque_len(const struct hip_challenge_response *response)
145{
146 HIP_ASSERT(response);
147 static const size_t min_len = sizeof(*response) -
148 sizeof(response->tlv) -
149 sizeof(response->opaque);
150
151 return hip_get_param_contents_len(&response->tlv) - min_len;
152}
153
154enum verification_result {
155 ERROR,
156 RESPONSE_CORRECT,
157 RESPONSE_INCORRECT,
158 RESPONSE_NO_MATCH
159};
160
161/**
162 * Helper function for verifying a CHALLENGE_RESPONSE parameter.
163 *
164 * @param ctx The packet context.
165 * @param response The CHALLENGE_RESPONSE parameter.
166 * @param midauth_nonce The stored nonce for this association.
167 * @return ERROR on validation error,
168 * RESPONSE_CORRECT if validation was successful,
169 * RESPONSE_INCORRECT if nonces match but solution is incorrect, and
170 * RESPONSE_NO_MATCH if no matching nonces are stored.
171 */
172static enum verification_result verify_response(const struct hip_fw_context *const ctx,
173 const struct hip_challenge_response *const response,
174 const uint8_t midauth_nonce[MIDAUTH_DEFAULT_NONCE_LENGTH])
175{
176 HIP_ASSERT(ctx);
177 HIP_ASSERT(response);
178 HIP_ASSERT(midauth_nonce);
179
180 //
181 // TODO: - check lifetime
182 // - compare with connection state entry (K, nonce)
183 // - use HITs from packet or from ctx?
184 //
185
186 const uint8_t len = hip_challenge_response_opaque_len(response);
187 const bool match = (len == MIDAUTH_DEFAULT_NONCE_LENGTH) &&
188 (memcmp(response->opaque, midauth_nonce,
189 MIDAUTH_DEFAULT_NONCE_LENGTH) == 0);
190
191 if (!match) {
192 return RESPONSE_NO_MATCH;
193 }
194
195 if (response->K < DEFAULT_DIFFICULTY) {
196 return RESPONSE_INCORRECT;
197 }
198
199 const struct hip_common *const hip = ctx->transport_hdr.hip;
200
201 if (response->K > 0) {
202 struct puzzle_hash_input tmp_puzzle;
203
204 if (hip_midauth_puzzle_seed(response->opaque, len, tmp_puzzle.puzzle)) {
205 HIP_ERROR("failed to derive midauth puzzle\n");
206 return ERROR;
207 }
208 tmp_puzzle.initiator_hit = hip->hits;
209 tmp_puzzle.responder_hit = hip->hitr;
210 memcpy(tmp_puzzle.solution, response->J, PUZZLE_LENGTH);
211
212 if (hip_verify_puzzle_solution(&tmp_puzzle, response->K)) {
213 return RESPONSE_INCORRECT;
214 }
215 }
216
217 return RESPONSE_CORRECT;
218}
219
220/**
221 * Verify a puzzle solution in the CHALLENGE_RESPONSE parameter.
222 *
223 * @param ctx The packet context.
224 * @param midauth_nonce The stored nonce for this association.
225 * @return 1 on success, 0 otherwise
226 */
227int hipfw_midauth_verify_challenge(const struct hip_fw_context *const ctx,
228 const uint8_t midauth_nonce[MIDAUTH_DEFAULT_NONCE_LENGTH])
229{
230 const struct hip_challenge_response *response;
231
232 HIP_ASSERT(ctx);
233
234 if (use_midauth) {
235 HIP_ASSERT(ctx->packet_type == HIP_PACKET);
236
237 response = hip_get_param(ctx->transport_hdr.hip,
238 HIP_PARAM_CHALLENGE_RESPONSE);
239 if (!response) {
240 HIP_ERROR("Challenge response expected but not found\n");
241 return ignore_missing_challenge_response ? 1 : 0;
242 }
243
244 bool found = false;
245 do {
246 switch (verify_response(ctx, response, midauth_nonce)) {
247 case RESPONSE_CORRECT:
248 HIP_DEBUG("Correct CHALLENGE_RESPONSE found\n");
249 return 1;
250 case RESPONSE_INCORRECT:
251 HIP_ERROR("Incorrect CHALLENGE_RESPONSE found\n");
252 if (notify_failed_challenge) {
253 // TODO: notify peer (ICMP, HIP notify)
254 HIP_DEBUG("STUB: notify\n");
255 }
256
257 if (!ignore_wrong_challenge_solution) {
258 return 0;
259 }
260 break;
261 case RESPONSE_NO_MATCH:
262 break;
263 default:
264 HIP_ERROR("Unable to compute challenge verification.\n");
265 break;
266 }
267
268 response = (const struct hip_challenge_response *)
269 hip_get_next_param(ctx->transport_hdr.hip, &response->tlv);
270 } while (response &&
271 hip_get_param_type(response) == HIP_PARAM_CHALLENGE_RESPONSE);
272
273 if (!found) {
274 HIP_ERROR("CHALLENGE_RESPONSE found, but no matching nonce\n");
275 return ignore_missing_challenge_response ? 1 : 0;
276 }
277
278 return found ? 1 : 0;
279 }
280
281 return 1;
453}282}
454283
=== modified file 'firewall/midauth.h'
--- firewall/midauth.h 2011-08-15 14:11:56 +0000
+++ firewall/midauth.h 2011-10-25 12:58:23 +0000
@@ -29,58 +29,19 @@
29#define _BSD_SOURCE29#define _BSD_SOURCE
3030
31#include <stdint.h>31#include <stdint.h>
3232#include <stdbool.h>
33#include "lib/core/protodefs.h"33
34#include "modules/midauth/lib/midauth_builder.h"34#define MIDAUTH_DEFAULT_NONCE_LENGTH 18
35
35#include "firewall_defines.h"36#include "firewall_defines.h"
3637
37typedef int (*midauth_handler)(struct hip_fw_context *ctx);38extern bool use_midauth;
3839
39struct midauth_handlers {
40 midauth_handler i1;
41 midauth_handler r1;
42 midauth_handler i2;
43 midauth_handler r2;
44 midauth_handler u1;
45 midauth_handler u2;
46 midauth_handler u3;
47 midauth_handler close;
48 midauth_handler close_ack;
49};
50
51/**
52 * Accepts a packet. Used in midauth_handlers as a default handler.
53 *
54 * @param ctx context of the packet
55 * @return NF_ACCEPT
56 */
57int midauth_handler_accept(struct hip_fw_context *ctx);
58
59int midauth_verify_challenge_response(const struct hip_challenge_response *const solution,
60 const hip_hit_t initiator_hit,
61 const hip_hit_t responder_hit);
62
63
64
65/**
66 * Insert a CHALLENGE_REQUEST parameter into a HIP packet.
67 *
68 * @param ctx context of the packet to be modified
69 * @param val_K challenge_request parameter val_K
70 * @param ltime challenge_request parameter lifetime
71 * @param opaque challenge_request parameter opaque
72 * @param opaque_len length of opaque
73 * @return 0 on success
74 */
75int midauth_add_challenge_request(struct hip_fw_context *ctx,
76 uint8_t val_K, uint8_t ltime,
77 uint8_t *opaque, uint8_t opaque_len);
78
79/**
80 * Initialize midauth infrastructure.
81 */
82void midauth_init(void);40void midauth_init(void);
8341
84int midauth_filter_hip(struct hip_fw_context *ctx);42int hipfw_midauth_add_challenge(struct hip_fw_context *const ctx,
43 uint8_t *const midauth_nonce);
44int hipfw_midauth_verify_challenge(const struct hip_fw_context *const ctx,
45 const uint8_t *const midauth_nonce);
8546
86#endif /* HIP_FIREWALL_MIDAUTH_H */47#endif /* HIP_FIREWALL_MIDAUTH_H */
8748
=== modified file 'firewall/pisa.h'
--- firewall/pisa.h 2011-08-15 14:11:56 +0000
+++ firewall/pisa.h 2011-10-25 12:58:23 +0000
@@ -31,12 +31,14 @@
31#define PISA_STATE_DISALLOW 031#define PISA_STATE_DISALLOW 0
32#define PISA_STATE_ALLOW 132#define PISA_STATE_ALLOW 1
3333
34#ifdef CONFIG_HIP_PISA
34/**35/**
35 * Register PISA handlers with midauth and initialize data structures.36 * Register PISA handlers with midauth and initialize data structures.
36 *37 *
37 * @param h pointer to the handlers38 * @param h pointer to the handlers
38 */39 */
39void pisa_init(struct midauth_handlers *h);40void pisa_init(struct midauth_handlers *h);
41#endif
4042
41/**43/**
42 * Check if a new random number is necessary.44 * Check if a new random number is necessary.
4345
=== added file 'firewall/rewrite.c'
--- firewall/rewrite.c 1970-01-01 00:00:00 +0000
+++ firewall/rewrite.c 2011-10-25 12:58:23 +0000
@@ -0,0 +1,380 @@
1/*
2 * Copyright (c) 2011 Aalto University and RWTH Aachen University.
3 *
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use,
8 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following
11 * conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26/**
27 * @file
28 *
29 * Support and utility functions for packet rewriting, especially for growing
30 * packets.
31 *
32 * Note that the buffer supplied to ipq_get_packet() in the firewall main loop
33 * is not big enough to hold both the ipq_packet header and ::HIP_MAX_PACKET
34 * bytes of payload.
35 * Furthermore, the actual amount of writable data behind the received payload
36 * is not documented by the libipq team. This makes sense if you consider that
37 * netlink is able to push multiple packets into our userspace buffer for
38 * efficiency reasons. Unfortunately, it is not documented whether libipq
39 * actually makes use of this feature either.
40 *
41 * For this reason, all packet rewriting that needs access beyond the boundaries
42 * of the originally received packet should copy it into a big, temporary buffer
43 * first. This is managed by the hip_fw_context_enable_write() function; see its
44 * documentation for more info.
45 *
46 * After growing, the data_len field and the length of the innermost frame
47 * (currently either HIP oder ESP) must be updated: Checksums and outer length
48 * fields are updated only once, right before reinjecting the packet.
49 *
50 * @note Copying the packet incurs a considerable performance hit. Browsing the
51 * source code of libipq, netfilter_queue and netlink, one can find
52 * assumptions about the original buffer and its usage to save copying in
53 * some cases, but unless the internals of these interfaces are documented
54 * more thoroughly, these optimizations should be considered hacks (and
55 * are thus not used here).
56 *
57 * @author Christof Mroz <christof.mroz@rwth-aachen.de>
58 */
59
60#define _BSD_SOURCE
61
62#include <netinet/in.h>
63#include <linux/netfilter.h>
64#include <libipq.h>
65#include <limits.h>
66#include <stdlib.h>
67#include <string.h>
68
69#include "lib/core/builder.h"
70#include "lib/core/debug.h"
71#include "lib/tool/checksum.h"
72#include "rewrite.h"
73
74// static configuration
75static const bool assume_ipq_buffer_sufficient = false;
76
77struct scratch_buffer {
78 ipq_packet_msg_t ipq;
79 uint8_t *payload[HIP_MAX_PACKET];
80} __attribute__((packed)); // no gaps between header and payload
81
82static struct scratch_buffer scratch_buffer;
83
84/**
85 * Given the address @a field of a struct member of @a old, return
86 * the same field's address but offset from @a new.
87 *
88 * As an example use case, say we have a pointer into @a old:
89 * <code>
90 * char old[LEN];
91 * ptr = &old[BLA];
92 * </code>
93 * Now after copying @a old to @a new, we need to update the pointer:
94 * <code>
95 * ptr = rebase(ptr, old, new);
96 * </code>
97 *
98 * @note This is essentially equivalent to
99 * <code>
100 * return &new.field
101 * </code>
102 * But of course, the above can only be used if we actually know
103 * the name of @a field, while this function needs just the
104 * address and base pointer.
105 */
106static void *rebase(const void *const field,
107 const void *const old,
108 void *const new)
109{
110 HIP_ASSERT((const char *) field >= (const char *) old);
111 return (char *) new + ((const char *) field - (const char *) old);
112}
113
114/**
115 * Mark packet as modified and indicate that the packet buffer passed by libipq
116 * is overwritten with packet content.
117 *
118 * @param ctx The current packet context.
119 *
120 * @note Only set this flag when sure that the new packet will not exceed the
121 * buffer length of the packet originally passed by libipq.
122 */
123static void hip_fw_context_enable_write_inplace(struct hip_fw_context *const ctx)
124{
125 ctx->modified = 1;
126}
127
128/**
129 * Mark packet as modified and enable rewritten packet to grow up to
130 * ::HIP_MAX_PACKET bytes.
131 * The buffer will be available via the ipq_packet->payload member of @a ctx, as
132 * usual. That is: To the caller, it should look like nothing happened.
133 *
134 * @param ctx The current packet context. The ipq header may have been modified
135 * but should be consistent, especially the data_len field.
136 *
137 * @note It is safe to call this function on the same @a ctx multiple times: the
138 * packet will not needlessly be copied again.
139 */
140static void hip_fw_context_enable_write(struct hip_fw_context *const ctx)
141{
142 HIP_ASSERT(ctx);
143 HIP_ASSERT(ctx->ipq_packet);
144
145 if (assume_ipq_buffer_sufficient) {
146 hip_fw_context_enable_write_inplace(ctx);
147 return;
148 }
149
150 if (ctx->ipq_packet != &scratch_buffer.ipq) {
151 // simply rebase the old pointers
152 if (ctx->ip_version == 4) {
153 ctx->ip_hdr.ipv4 = rebase(ctx->ip_hdr.ipv4, ctx->ipq_packet,
154 &scratch_buffer.ipq);
155 } else {
156 HIP_ASSERT(ctx->ip_version == 6);
157 ctx->ip_hdr.ipv6 = rebase(ctx->ip_hdr.ipv6, ctx->ipq_packet,
158 &scratch_buffer.ipq);
159 }
160
161 switch (ctx->packet_type) {
162 case ESP_PACKET:
163 ctx->transport_hdr.esp = rebase(ctx->transport_hdr.esp, ctx->ipq_packet,
164 &scratch_buffer.ipq);
165 break;
166 case HIP_PACKET:
167 ctx->transport_hdr.hip = rebase(ctx->transport_hdr.hip, ctx->ipq_packet,
168 &scratch_buffer.ipq);
169 break;
170 case OTHER_PACKET:
171 break;
172 default:
173 HIP_ASSERT(false);
174 }
175
176 if (ctx->udp_encap_hdr) {
177 ctx->udp_encap_hdr = rebase(ctx->udp_encap_hdr, ctx->ipq_packet,
178 &scratch_buffer.ipq);
179 }
180
181 // copy ipq packet plus payload
182 memcpy(&scratch_buffer.ipq, ctx->ipq_packet,
183 sizeof(*ctx->ipq_packet) + ctx->ipq_packet->data_len);
184 ctx->ipq_packet = &scratch_buffer.ipq;
185 ctx->modified = 1;
186 } else {
187 // second invocation
188 HIP_ASSERT(ctx->modified);
189 }
190}
191
192/**
193 * Add a new parameter to the correct position in the packet. Parameters are
194 * ordered by type number. Hence, some parameters might need to be moved in
195 * order for the new parameter to fit into the right position.
196 *
197 * @param ctx The current packet context.
198 * @param param The parameter to be added to the packet.
199 * @return true on success, false otherwise.
200 */
201bool hipfw_splice_param(struct hip_fw_context *const ctx,
202 const struct hip_tlv_common *const param)
203{
204 HIP_ASSERT(ctx);
205 HIP_ASSERT(ctx->packet_type == HIP_PACKET);
206 HIP_ASSERT(param);
207
208 const size_t hip_len = hip_get_msg_total_len(ctx->transport_hdr.hip); // padded
209 const size_t param_len = hip_get_param_total_len(param); // padded
210 const hip_tlv param_type = hip_get_param_type(param);
211 const size_t contents_len = hip_get_param_contents_len(param); // not padded
212
213 // RFC 5201: Types 0 - 1023 are signed, so they must not be moved
214 HIP_ASSERT(param_type >= 1024);
215
216 if (ctx->ipq_packet->data_len + param_len > sizeof(scratch_buffer.payload)) {
217 HIP_ERROR("New parameter of type %u, effective size %u, "
218 "does not fit into packet", param_type, param_len);
219 return false;
220 }
221
222 hip_fw_context_enable_write(ctx);
223
224 // note: this works because param_len is padded! otherwise, resize the hip
225 // packet and call hip_get_msg_total_len() instead.
226 ctx->ipq_packet->data_len += param_len;
227
228 struct hip_common *const hip = ctx->transport_hdr.hip;
229 uint8_t *const end = ((uint8_t *) hip) + hip_len;
230 struct hip_tlv_common *current = NULL;
231 uint8_t *out = end; // append by default
232
233 while ((current = hip_get_next_param_readwrite(hip, current))) {
234 if (hip_get_param_type(current) >= param_type) {
235 uint8_t *const splice = (uint8_t *const) current;
236
237 memmove(splice + param_len, splice, end - splice);
238 out = splice;
239 break;
240 }
241 }
242
243 if ((sizeof(struct hip_tlv_common) + contents_len) != param_len) {
244 // padding needed: don't send uninitialized data
245 memset(out, 0, param_len);
246 }
247
248 memcpy(out, param, sizeof(struct hip_tlv_common) + contents_len);
249 hip_set_msg_total_len(hip, hip_len + param_len); // IP length etc. will be inferred
250
251 return true;
252}
253
254/**
255 * Getter for the position of the IP payload in an IPv4 packet. This allows to
256 * handle IP options.
257 *
258 * @param ipv4 The IPv4 packet.
259 */
260inline static void *get_ipv4_payload(struct ip *const ipv4)
261{
262 return ((uint8_t *) ipv4) + 4 * ipv4->ip_hl;
263}
264
265/**
266 * Update the UDP header after modifying the higher layer packet content.
267 *
268 * @param udp The UDP packet.
269 * @param payload_len The length of the UDP payload.
270 * @param src_ip The source IP address (needed for pseudo-header).
271 * @param dst_ip The destination IP address (needed for pseudo-header).
272 */
273static void update_udp_header(struct udphdr *const udp,
274 const size_t payload_len,
275 const struct in_addr src_ip,
276 const struct in_addr dst_ip)
277{
278 const uint16_t tot_len = sizeof(*udp) + payload_len;
279
280 HIP_ASSERT(sizeof(*udp) == 8);
281
282 udp->len = htons(tot_len);
283 udp->check = htons(0);
284 udp->check = ipv4_checksum(IPPROTO_UDP, &src_ip, &dst_ip, udp, tot_len);
285}
286
287/**
288 * Update the IPv4 header after modifying the higher layer packet content.
289 *
290 * @param ipv4 The IPv4 packet.
291 * @param payload_len The length of the IPv4 payload.
292 */
293static void update_ipv4_header(struct ip *const ipv4,
294 const size_t payload_len)
295{
296 ipv4->ip_len = htons(ipv4->ip_hl * 4 + payload_len);
297 ipv4->ip_sum = htons(0);
298 ipv4->ip_sum = checksum_ip(ipv4, ipv4->ip_hl);
299}
300
301/**
302 * Update the IPv6 header after modifying the higher layer packet content.
303 *
304 * @param ipv6 The IPv6 packet.
305 * @param payload_len The length of the IPv6 payload.
306 */
307static void update_ipv6_header(struct ip6_hdr *const ipv6,
308 const size_t payload_len)
309{
310 ipv6->ip6_plen = htons(payload_len);
311}
312
313/**
314 * Set an accept verdict for a modified packet
315 *
316 * @param handle libipq file handle
317 * @param ctx The current packet context.
318 *
319 */
320void allow_modified_packet(struct ipq_handle *const handle,
321 struct hip_fw_context *const ctx)
322{
323 HIP_ASSERT(ctx->modified);
324
325 //
326 // TODO: send as separate packets if fragmented?
327 //
328
329 if (ctx->packet_type == HIP_PACKET) {
330 struct hip_common *const hip = ctx->transport_hdr.hip;
331 const size_t hip_len = hip_get_msg_total_len(hip);
332
333 if (ctx->ip_version == 4) {
334 struct ip *const ipv4 = ctx->ip_hdr.ipv4;
335
336 if (ipv4->ip_p == IPPROTO_UDP) {
337 // UDP Payload: "zero SPI" (0x00000000) + HIP
338 const size_t udp_len = HIP_UDP_ZERO_BYTES_LEN + hip_len;
339
340 update_udp_header(get_ipv4_payload(ipv4), udp_len,
341 ipv4->ip_src, ipv4->ip_dst);
342 update_ipv4_header(ipv4, sizeof(struct udphdr) + udp_len);
343 // HIP checksum unused
344 } else {
345 const struct sockaddr_in src = { .sin_family = AF_INET,
346 .sin_addr = ipv4->ip_src };
347 const struct sockaddr_in dst = { .sin_family = AF_INET,
348 .sin_addr = ipv4->ip_dst };
349
350 HIP_ASSERT(ipv4->ip_p == IPPROTO_HIP);
351
352 hip_zero_msg_checksum(hip);
353 hip->checksum = hip_checksum_packet((char *) hip,
354 (const struct sockaddr *) &src,
355 (const struct sockaddr *) &dst);
356 update_ipv4_header(ipv4, hip_len);
357 }
358 } else {
359 HIP_ASSERT(ctx->ip_version == 6);
360
361 struct ip6_hdr *const ipv6 = ctx->ip_hdr.ipv6;
362 const struct sockaddr_in6 src = { .sin6_family = AF_INET6,
363 .sin6_addr = ipv6->ip6_src };
364 const struct sockaddr_in6 dst = { .sin6_family = AF_INET6,
365 .sin6_addr = ipv6->ip6_dst };
366
367 HIP_ASSERT(ipv6->ip6_nxt == IPPROTO_HIP);
368
369 hip_zero_msg_checksum(hip);
370 hip->checksum = hip_checksum_packet((char *) hip,
371 (const struct sockaddr *) &src,
372 (const struct sockaddr *) &dst);
373 update_ipv6_header(ipv6, hip_len);
374 }
375 }
376
377 ipq_set_verdict(handle, ctx->ipq_packet->packet_id, NF_ACCEPT,
378 ctx->ipq_packet->data_len, ctx->ipq_packet->payload);
379 HIP_DEBUG("Packet accepted with modifications\n\n");
380}
0381
=== added file 'firewall/rewrite.h'
--- firewall/rewrite.h 1970-01-01 00:00:00 +0000
+++ firewall/rewrite.h 2011-10-25 12:58:23 +0000
@@ -0,0 +1,39 @@
1/*
2 * Copyright (c) 2011 Aalto University and RWTH Aachen University.
3 *
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use,
8 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following
11 * conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26#ifndef HIP_FIREWALL_REWRITE_H
27#define HIP_FIREWALL_REWRITE_H
28
29#include <stdbool.h>
30
31#include "firewall_defines.h"
32
33
34bool hipfw_splice_param(struct hip_fw_context *const ctx,
35 const struct hip_tlv_common *const param);
36void allow_modified_packet(struct ipq_handle *const handle,
37 struct hip_fw_context *const ctx);
38
39#endif /* HIP_FIREWALL_REWRITE_H */
040
=== modified file 'lib/tool/checksum.c'
--- lib/tool/checksum.c 2011-08-15 14:11:56 +0000
+++ lib/tool/checksum.c 2011-10-25 12:58:23 +0000
@@ -57,15 +57,18 @@
57 * @param protocol protocol57 * @param protocol protocol
58 * @return the calculated IPv4 header checksum58 * @return the calculated IPv4 header checksum
59 */59 */
60uint16_t ipv4_checksum(uint8_t protocol, void *s, void *d, void *c,60uint16_t ipv4_checksum(const uint8_t protocol,
61 uint16_t len)61 const void *const s,
62 const void *const d,
63 const void *const c,
64 const uint16_t len)
62{65{
63 uint8_t *src = s;66 const uint8_t *src = s;
64 uint8_t *dst = d;67 const uint8_t *dst = d;
65 uint8_t *data = c;68 const uint8_t *data = c;
66 uint16_t word16;69 uint16_t word16;
67 uint32_t sum;70 uint32_t sum;
68 uint16_t i;71 uint16_t i;
6972
70 /* initialize sum to zero */73 /* initialize sum to zero */
71 sum = 0;74 sum = 0;
@@ -219,23 +222,23 @@
219 * @return the checksum222 * @return the checksum
220 * @note Checksumming is from Boeing's HIPD.223 * @note Checksumming is from Boeing's HIPD.
221 */224 */
222uint16_t hip_checksum_packet(char *data, struct sockaddr *src,225uint16_t hip_checksum_packet(char *data, const struct sockaddr *src,
223 struct sockaddr *dst)226 const struct sockaddr *dst)
224{227{
225 uint16_t checksum = 0;228 uint16_t checksum = 0;
226 unsigned long sum = 0;229 unsigned long sum = 0;
227 int count = 0, length = 0;230 int count = 0, length = 0;
228 unsigned short *p = NULL; /* 16-bit */231 unsigned short *p = NULL; /* 16-bit */
229 struct pseudo_header pseudoh;232 struct pseudo_header pseudoh;
230 struct pseudo_header6 pseudoh6;233 struct pseudo_header6 pseudoh6;
231 uint32_t src_network, dst_network;234 uint32_t src_network, dst_network;
232 struct in6_addr *src6, *dst6;235 const struct in6_addr *src6, *dst6;
233 struct hip_common *hiph = (struct hip_common *) data;236 struct hip_common *hiph = (struct hip_common *) data;
234237
235 if (src->sa_family == AF_INET) {238 if (src->sa_family == AF_INET) {
236 /* IPv4 checksum based on UDP-- Section 6.1.2 */239 /* IPv4 checksum based on UDP-- Section 6.1.2 */
237 src_network = ((struct sockaddr_in *) src)->sin_addr.s_addr;240 src_network = ((const struct sockaddr_in *) src)->sin_addr.s_addr;
238 dst_network = ((struct sockaddr_in *) dst)->sin_addr.s_addr;241 dst_network = ((const struct sockaddr_in *) dst)->sin_addr.s_addr;
239242
240 memset(&pseudoh, 0, sizeof(struct pseudo_header));243 memset(&pseudoh, 0, sizeof(struct pseudo_header));
241 memcpy(&pseudoh.src_addr, &src_network, 4);244 memcpy(&pseudoh.src_addr, &src_network, 4);
@@ -248,8 +251,8 @@
248 p = (unsigned short *) &pseudoh;251 p = (unsigned short *) &pseudoh;
249 } else {252 } else {
250 /* IPv6 checksum based on IPv6 pseudo-header */253 /* IPv6 checksum based on IPv6 pseudo-header */
251 src6 = &((struct sockaddr_in6 *) src)->sin6_addr;254 src6 = &((const struct sockaddr_in6 *) src)->sin6_addr;
252 dst6 = &((struct sockaddr_in6 *) dst)->sin6_addr;255 dst6 = &((const struct sockaddr_in6 *) dst)->sin6_addr;
253256
254 memset(&pseudoh6, 0, sizeof(struct pseudo_header6));257 memset(&pseudoh6, 0, sizeof(struct pseudo_header6));
255 memcpy(&pseudoh6.src_addr[0], src6, 16);258 memcpy(&pseudoh6.src_addr[0], src6, 16);
256259
=== modified file 'lib/tool/checksum.h'
--- lib/tool/checksum.h 2010-07-16 17:39:09 +0000
+++ lib/tool/checksum.h 2011-10-25 12:58:23 +0000
@@ -8,13 +8,16 @@
8#include <netinet/ip.h>8#include <netinet/ip.h>
9#include <sys/socket.h>9#include <sys/socket.h>
1010
11uint16_t ipv4_checksum(uint8_t protocol, void *s, void *d, void *c, uint16_t len);11uint16_t ipv4_checksum(const uint8_t protocol, const void *const s,
12 const void *const d, const void *const c,
13 const uint16_t len);
12uint16_t ipv6_checksum(uint8_t protocol,14uint16_t ipv6_checksum(uint8_t protocol,
13 struct in6_addr *src,15 struct in6_addr *src,
14 struct in6_addr *dst,16 struct in6_addr *dst,
15 void *data, uint16_t len);17 void *data, uint16_t len);
16uint16_t checksum_ip(struct ip *ip_hdr, const unsigned int ip_hl);18uint16_t checksum_ip(struct ip *ip_hdr, const unsigned int ip_hl);
17uint16_t inchksum(const void *data, uint32_t length);19uint16_t inchksum(const void *data, uint32_t length);
18uint16_t hip_checksum_packet(char *data, struct sockaddr *src, struct sockaddr *dst);20uint16_t hip_checksum_packet(char *data, const struct sockaddr *src,
21 const struct sockaddr *dst);
1922
20#endif /* HIP_LIB_TOOL_CHECKSUM_H */23#endif /* HIP_LIB_TOOL_CHECKSUM_H */
2124
=== modified file 'packaging/openwrt/hipl/files/hipfw.init'
--- packaging/openwrt/hipl/files/hipfw.init 2011-06-15 12:45:43 +0000
+++ packaging/openwrt/hipl/files/hipfw.init 2011-10-25 12:58:23 +0000
@@ -4,7 +4,7 @@
4START=654START=65
5STOP=655STOP=65
66
7HIPFW_START='hipfw -kb'7HIPFW_START='hipfw -kbm'
8PID_FILE="/var/lock/hip_firewall.lock"8PID_FILE="/var/lock/hip_firewall.lock"
99
10# check if daemon is already running10# check if daemon is already running
1111
=== modified file 'test/check_firewall.c'
--- test/check_firewall.c 2011-04-04 16:36:55 +0000
+++ test/check_firewall.c 2011-10-25 12:58:23 +0000
@@ -36,7 +36,9 @@
36 srunner_add_suite(sr, firewall_file_buffer());36 srunner_add_suite(sr, firewall_file_buffer());
37 srunner_add_suite(sr, firewall_helpers());37 srunner_add_suite(sr, firewall_helpers());
38 srunner_add_suite(sr, firewall_line_parser());38 srunner_add_suite(sr, firewall_line_parser());
39 srunner_add_suite(sr, firewall_midauth());
39 srunner_add_suite(sr, firewall_port_bindings());40 srunner_add_suite(sr, firewall_port_bindings());
41 srunner_add_suite(sr, firewall_rewrite());
4042
41 srunner_run_all(sr, CK_NORMAL);43 srunner_run_all(sr, CK_NORMAL);
42 number_failed = srunner_ntests_failed(sr);44 number_failed = srunner_ntests_failed(sr);
4345
=== added file 'test/firewall/midauth.c'
--- test/firewall/midauth.c 1970-01-01 00:00:00 +0000
+++ test/firewall/midauth.c 2011-10-25 12:58:23 +0000
@@ -0,0 +1,298 @@
1/*
2 * Copyright (c) 2011 Aalto University and RWTH Aachen University.
3 *
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use,
8 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following
11 * conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26#define _BSD_SOURCE
27
28#include "config.h"
29#include "firewall/firewall.c"
30#include "firewall/firewall_defines.h"
31#include "firewall/midauth.h"
32#include "firewall/midauth.c"
33#include "modules/midauth/lib/midauth_builder.h"
34#include "test_suites.h"
35#include "test/mocks.h"
36
37START_TEST(test_hipfw_midauth_add_challenge)
38{
39 struct hip_fw_context ctx;
40 uint8_t midauth_nonce[MIDAUTH_DEFAULT_NONCE_LENGTH];
41 const struct hip_challenge_request *challenge = NULL;
42 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"
43 "\x93\x28\x06\x00\x00\x00\x00\x00\x02\x00\x00\x00\x65\x74\x68\x32\x00\x00\x00\x00\x00\x00\x00\x00"
44 "\x00\x00\x00\x00\x65\x74\x68\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x01\x00"
45 "\x06\x08\x00\x27\x79\x45\x6B\x00\x00\x00\x00\x00\x00\x00\x00\x00\x18\x03\x00\x00\x00\x00\x00\x00"
46 "\x45\x00\x03\x18\x00\x00\x40\x00\x3F\x11\x1D\xD3\x0A\x00\x04\x02\x0A\x00\x03\x01\x29\x04\x29\x04"
47 "\x03\x04\x00\x00\x00\x00\x00\x00\x3B\x5E\x02\x11\x00\x00\x00\x00\x20\x01\x00\x10\xD5\x79\x52\xA7"
48 "\xFA\xC2\x99\x64\xC9\x36\xA9\x40\x20\x01\x00\x19\x9C\x8E\x9A\x92\xD5\x68\xD2\x87\x7F\x3F\x6F\x95"
49 "\x01\x01\x00\x0C\x00\x2A\x48\x49\xF3\xAC\x4C\x3F\x25\x09\xCC\x58\x02\x01\x00\xF6\x03\x00\xC0\x33"
50 "\xAE\x3C\x0A\x08\xC3\x47\x2B\x46\xB2\xDD\xE7\xFA\x5E\xC7\x5E\x25\xEE\x8B\x4A\xF4\xF2\xEE\xB8\x25"
51 "\x7C\x74\x6F\x3C\x1C\x4F\x51\x87\xF3\xF4\x0E\x8E\x88\xDA\xFF\x55\x2D\x51\x4E\xEB\x2F\x4B\x8D\x89"
52 "\xE5\xAD\xEA\xD5\x87\x0D\x20\x9C\xF6\x93\x0A\x05\x2A\x29\x52\x05\x91\x84\x70\xF9\xBE\xF2\x87\x04"
53 "\x4D\x5C\x7F\xC9\x20\x8D\x76\x22\xEC\xA5\x0D\x6C\x06\xB5\xB2\x30\x76\x01\x52\x4B\xCD\xD8\x41\xAD"
54 "\x59\x95\x0B\xE2\xEC\xAF\xC3\x95\xFA\xB1\x3B\xE2\x06\x51\xB0\x4B\x3F\x6C\x61\xDB\xF1\x08\x25\x11"
55 "\xBE\xB6\x4B\x39\x6F\x72\x03\x80\x3A\x4A\x86\xFE\xC4\xC0\x9D\x8B\x8E\x88\x99\x06\xF0\x72\x29\xC6"
56 "\x66\xA8\x31\x36\x38\x50\x10\x4F\xD5\xF7\xAE\x39\xDD\xB1\x47\x4B\x14\x59\xA5\x21\x1C\x60\x2D\xF0"
57 "\xB7\x16\x71\xEA\xA8\x7B\xC5\xD1\x7F\x60\xD2\xE5\x36\xEF\xED\xBC\xE3\x9E\x63\x85\x19\xC5\xE1\x01"
58 "\x00\x30\x4E\x9E\x69\x8F\x6E\xFA\xAF\x95\x9F\x55\x78\x25\xE1\x48\x59\x40\x1D\x5A\x14\x5A\xB2\xA3"
59 "\x86\x67\x1C\xE9\x80\x5A\x7A\xC0\xE6\xFE\x6D\x96\x2B\xC5\x8C\x54\x20\xAE\x15\xFA\x7B\xEC\xF9\x1C"
60 "\x35\xAB\x00\x00\x00\x00\x00\x00\x02\x41\x00\x06\x00\x01\x00\x02\x00\x05\x00\x00\x00\x00\x00\x00"
61 "\x02\xC1\x00\xD4\x00\xC8\x10\x08\x02\x02\xFF\x05\x03\x01\x00\x01\xD9\x83\x29\xBE\xF8\x4C\x5A\xCC"
62 "\x9B\x71\x0B\x4E\x26\xCE\x2A\x21\x6C\x29\xC0\x2A\x16\x38\xD1\x92\xE3\x1B\x25\x9D\x65\x24\xF5\x83"
63 "\x18\x0D\x61\xE7\xA9\x09\x09\x9C\x8F\xBF\xC1\x07\x02\xBF\x62\x0D\x82\x62\x4C\x81\xEB\x3A\xE2\x62"
64 "\x19\xEB\x51\x7A\x12\xDF\x24\x37\x5F\x18\xB4\xF1\x28\xD6\x08\xFF\xE0\x6B\x48\x4E\x13\xC1\x61\x1E"
65 "\x72\xF1\xD6\x32\xA1\x43\x42\x37\x66\x45\x6F\x4A\x7A\x92\x51\xE0\x98\x1D\x0F\x92\x18\x37\xB7\xCC"
66 "\xCC\x84\xF9\x61\x6C\xE8\xF6\xD7\x3D\xF3\x1D\x04\x4F\xD1\x4C\xA8\x78\x63\x73\xAD\x9C\x2B\xBE\x4D"
67 "\x25\x1B\xC5\x9C\x5D\x0F\x6C\xC6\x21\x01\xD1\xFA\xAD\x62\x3C\x5E\x17\x46\xF9\x2C\xE8\xC8\xE2\x8A"
68 "\xC0\x04\xD6\x72\xBE\x9E\x25\xB6\x25\x3C\x11\x1F\x8A\x9F\xE7\xAC\x8F\xBC\xD3\x76\x36\xEC\x7E\x41"
69 "\xB9\xBC\x5D\x8F\xC1\xD9\x82\x99\xEA\x9B\x70\x00\xA0\xEB\x08\x2F\x74\x68\x65\x73\x69\x73\x32\x00"
70 "\x0F\xFF\x00\x08\x00\x00\x00\x01\x00\x02\x00\x05\x00\x00\x00\x00\xF0\xC1\x00\xC1\x05\x2D\x6F\xDE"
71 "\xF9\xCE\x0F\x79\x4E\xA3\x21\x73\x0E\x84\x22\x55\x0C\xCC\x43\xBD\x73\xD3\xA3\x8E\xE8\xC1\xA3\xB6"
72 "\x69\x0C\xF7\x12\xA9\x10\x7E\x56\xED\xA2\x83\x23\x19\x6D\x9C\xF1\x65\x22\xFC\xB1\x3A\x96\xC7\xF3"
73 "\x35\x9C\xAF\xC8\x2B\x38\x21\x03\xB7\xAE\x8D\xE3\x2D\x92\x2C\x66\x90\x03\xD9\x44\xC6\xA5\xAF\x4B"
74 "\xBB\x65\x3A\x50\x84\x33\x2C\x0B\x3D\x59\xF8\x57\x27\x9C\xB1\xB6\x73\xC5\xEE\xC2\x68\x52\x35\x9C"
75 "\x41\xD7\x11\x6E\xEC\xF5\x20\x7D\xB8\xB4\x4E\xDD\x20\x94\xA0\x1B\xD8\x60\x8C\x5F\xC1\xB4\x9C\x3C"
76 "\xE8\xA3\x99\x81\x6B\xF9\x0D\xE4\xE6\xD9\x34\xD6\x8A\xB5\xBD\xAA\x66\x43\x13\xE0\x30\x9A\x07\x46"
77 "\xCD\x9D\x6F\x63\xFF\x5E\x05\x54\xDC\xA9\x10\x3C\x2D\xDF\x62\xAD\x18\x13\x74\x61\x92\xD3\xF7\x65"
78 "\xAD\x34\xB1\x4D\xB5\x65\x62\x8A\xD4\x7C\xBC\xF7\xC1\x29\x0F\x92\xB8\xB3\xC9\x05\x4A\x00\x00";
79
80 use_midauth = 1;
81 mock_ipq = 1;
82 mock_ipq_pkt_len = ARRAY_SIZE(buf);
83
84 HIP_DEBUG("Testing hipfw_midauth_add_challenge with valid inputs \n");
85
86 fail_unless(hip_fw_init_context(&ctx, buf, 4) == 0, NULL);
87
88 fail_unless(hipfw_midauth_add_challenge(&ctx, midauth_nonce) == 1, NULL);
89 fail_unless((challenge = hip_get_param(ctx.transport_hdr.hip, HIP_PARAM_CHALLENGE_REQUEST)) != NULL, 0);
90 fail_unless(memcmp(challenge->opaque, midauth_nonce, MIDAUTH_DEFAULT_NONCE_LENGTH) == 0, NULL);
91 fail_unless(challenge->K >= DEFAULT_DIFFICULTY, NULL);
92}
93END_TEST
94
95#ifdef HAVE_TCASE_ADD_EXIT_TEST
96START_TEST(test_hipfw_midauth_add_challenge_NULL_ctx)
97{
98 struct hip_fw_context ctx;
99
100 HIP_DEBUG("Testing NULL nonce \n");
101 use_midauth = true;
102 hipfw_midauth_add_challenge(&ctx, NULL);
103}
104END_TEST
105
106START_TEST(test_hipfw_midauth_add_challenge_NULL_nonce)
107{
108 uint8_t nonce[18];
109
110 HIP_DEBUG("Testing NULL ctx \n");
111 use_midauth = true;
112 hipfw_midauth_add_challenge(NULL, nonce);
113}
114END_TEST
115#endif /* HAVE_TCASE_ADD_EXIT_TEST */
116
117START_TEST(test_hip_challenge_response_opaque_len)
118{
119 struct hip_challenge_response response;
120
121 HIP_DEBUG("Testing hip_challenge_response_opaque_len \n");
122
123 hip_set_param_contents_len(&response.tlv, 28);
124 fail_unless(hip_challenge_response_opaque_len(&response) == 18, NULL);
125
126 hip_set_param_contents_len(&response.tlv, 11);
127 fail_unless(hip_challenge_response_opaque_len(&response) == 1, NULL);
128}
129END_TEST
130
131#ifdef HAVE_TCASE_ADD_EXIT_TEST
132START_TEST(test_hip_challenge_response_opaque_len_NULL)
133{
134 HIP_DEBUG("Testing hip_challenge_response_opaque_len on NULL input\n");
135 hip_challenge_response_opaque_len(NULL);
136}
137END_TEST
138
139START_TEST(test_verify_response_NULL_ctx)
140{
141 struct hip_challenge_response response;
142 uint8_t midauth_nonce[MIDAUTH_DEFAULT_NONCE_LENGTH];
143
144 verify_response(NULL, &response, midauth_nonce);
145}
146END_TEST
147
148START_TEST(test_verify_response_NULL_response)
149{
150 struct hip_fw_context ctx;
151 uint8_t midauth_nonce[MIDAUTH_DEFAULT_NONCE_LENGTH];
152
153 verify_response(&ctx, NULL, midauth_nonce);
154}
155END_TEST
156
157START_TEST(test_verify_response_NULL_nonce)
158{
159 struct hip_fw_context ctx;
160 struct hip_challenge_response response;
161
162 verify_response(&ctx, &response, NULL);
163}
164END_TEST
165#endif /* HAVE_TCASE_ADD_EXIT_TEST */
166
167START_TEST(test_verify_response_no_match)
168{
169 struct hip_fw_context ctx;
170 struct hip_challenge_response response;
171 uint8_t midauth_nonce[] = "\x01\x41\x01\x14\x05\x00\x48\x49\x0b"
172 "\x02\x42\x02\x15\x06\x08\x49\x50\x0d";
173
174 HIP_DEBUG("Testing verify_response on non-matching inputs\n");
175
176 hip_set_param_contents_len(&response.tlv, 28);
177 memcpy(response.opaque, midauth_nonce, MIDAUTH_DEFAULT_NONCE_LENGTH);
178 response.opaque[0]++;
179 fail_unless(verify_response(&ctx, &response, midauth_nonce) == 3, NULL);
180 response.opaque[0]--;
181
182 response.opaque[MIDAUTH_DEFAULT_NONCE_LENGTH - 1]++;
183 fail_unless(verify_response(&ctx, &response, midauth_nonce) == 3, NULL);
184}
185END_TEST
186
187START_TEST(test_verify_response)
188{
189 int i;
190 struct hip_common hip;
191 struct hip_fw_context ctx;
192 struct hip_challenge_response response;
193 struct puzzle_hash_input tmp_puzzle;
194 uint8_t midauth_nonce[] = "\x01\x41\x01\x14\x05\x00\x48\x49\x0b"
195 "\x02\x42\x02\x15\x06\x08\x49\x50\x0d";
196
197 HIP_DEBUG("Testing verify_response on valid inputs\n");
198
199 // build context
200 ctx.transport_hdr.hip = &hip;
201 hip.hits = in6addr_any;
202 hip.hitr = in6addr_any;
203
204 // build response
205 fail_unless(hip_midauth_puzzle_seed(midauth_nonce, MIDAUTH_DEFAULT_NONCE_LENGTH, tmp_puzzle.puzzle) == 0, NULL);
206 tmp_puzzle.initiator_hit = in6addr_any;
207 tmp_puzzle.responder_hit = in6addr_any;
208 hip_set_param_contents_len(&response.tlv, 28);
209 memcpy(response.opaque, midauth_nonce, MIDAUTH_DEFAULT_NONCE_LENGTH);
210 for (i = 1; i <= 20; i++) {
211 HIP_DEBUG("Difficulty: %i \n", i);
212 response.K = i;
213 fail_unless(hip_solve_puzzle(&tmp_puzzle, response.K) == 0, NULL);
214 memcpy(response.J, tmp_puzzle.solution, 8);
215 fail_unless(verify_response(&ctx, &response, midauth_nonce) == 1, NULL);
216 }
217}
218END_TEST
219
220START_TEST(test_hipfw_midauth_verify_challenge_NULL_ctx)
221{
222 uint8_t midauth_nonce[] = "\x01\x41\x01\x14\x05\x00\x48\x49\x0b"
223 "\x02\x42\x02\x15\x06\x08\x49\x50\x0d";
224 hipfw_midauth_verify_challenge(NULL, midauth_nonce);
225}
226END_TEST
227
228START_TEST(test_hipfw_midauth_verify_challenge_NULL_challenge)
229{
230 struct hip_fw_context ctx;
231 ctx.packet_type = HIP_PACKET;
232 use_midauth = true;
233 fail_unless(hipfw_midauth_verify_challenge(&ctx, NULL) == 0, NULL);
234}
235END_TEST
236
237START_TEST(test_hipfw_midauth_verify_challenge)
238{
239 struct hip_common *hip;
240 struct hip_fw_context ctx;
241 struct hip_challenge_request request;
242 struct puzzle_hash_input tmp_puzzle;
243 uint8_t midauth_nonce[] = "\x01\x41\x01\x14\x05\x00\x48\x49\x0b"
244 "\x02\x42\x02\x15\x06\x08\x49\x50\x0d";
245
246 HIP_DEBUG("Testing verify_response on valid inputs\n");
247
248 // build context
249 hip = hip_msg_alloc();
250 hip->hits = in6addr_any;
251 hip->hitr = in6addr_any;
252 ctx.transport_hdr.hip = hip;
253
254 // build request
255 request.K = 1;
256 request.tlv.type = HIP_PARAM_CHALLENGE_REQUEST;
257 hip_set_param_contents_len(&request.tlv, 20);
258 memcpy(request.opaque, midauth_nonce, 18);
259
260 // build solution
261 fail_unless(hip_midauth_puzzle_seed(midauth_nonce, MIDAUTH_DEFAULT_NONCE_LENGTH, tmp_puzzle.puzzle) == 0, NULL);
262 tmp_puzzle.initiator_hit = in6addr_any;
263 tmp_puzzle.responder_hit = in6addr_any;
264 fail_unless(hip_solve_puzzle(&tmp_puzzle, request.K) == 0, NULL);
265
266 // build parameter
267 hip_build_param_challenge_response(hip, &request, tmp_puzzle.solution);
268
269 fail_unless(hipfw_midauth_verify_challenge(&ctx, midauth_nonce) == 1, NULL);
270}
271END_TEST
272
273Suite *firewall_midauth(void)
274{
275 Suite *s = suite_create("firewall/midauth");
276 TCase *tc_midauth = tcase_create("Midauth");
277
278#ifdef HAVE_TCASE_ADD_EXIT_TEST
279 tcase_add_exit_test(tc_midauth, test_hipfw_midauth_add_challenge_NULL_ctx, 1);
280 tcase_add_exit_test(tc_midauth, test_hipfw_midauth_add_challenge_NULL_nonce, 1);
281 tcase_add_exit_test(tc_midauth, test_hip_challenge_response_opaque_len_NULL, 1);
282 tcase_add_exit_test(tc_midauth, test_verify_response_NULL_ctx, 1);
283 tcase_add_exit_test(tc_midauth, test_verify_response_NULL_response, 1);
284 tcase_add_exit_test(tc_midauth, test_verify_response_NULL_nonce, 1);
285 tcase_add_exit_test(tc_midauth, test_hipfw_midauth_verify_challenge_NULL_ctx, 1);
286#endif
287
288 tcase_add_test(tc_midauth, test_hipfw_midauth_add_challenge);
289 tcase_add_test(tc_midauth, test_hip_challenge_response_opaque_len);
290 tcase_add_test(tc_midauth, test_verify_response_no_match);
291 tcase_add_test(tc_midauth, test_verify_response);
292 tcase_add_test(tc_midauth, test_hipfw_midauth_verify_challenge_NULL_challenge);
293 tcase_add_test(tc_midauth, test_hipfw_midauth_verify_challenge);
294
295 suite_add_tcase(s, tc_midauth);
296
297 return s;
298}
0299
=== added file 'test/firewall/rewrite.c'
--- test/firewall/rewrite.c 1970-01-01 00:00:00 +0000
+++ test/firewall/rewrite.c 2011-10-25 12:58:23 +0000
@@ -0,0 +1,151 @@
1/*
2 * Copyright (c) 2011 Aalto University and RWTH Aachen University.
3 *
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use,
8 * copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following
11 * conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26#define _BSD_SOURCE
27
28#include <check.h>
29#include <stdlib.h>
30#include <string.h>
31
32#include "firewall/firewall_defines.h"
33#include "lib/core/common.h"
34#include "modules/midauth/hipd/midauth.h"
35#include "modules/midauth/lib/midauth_builder.h"
36#include "test/mocks.h"
37#include "test_suites.h"
38
39#include "firewall/firewall.c"
40
41
42static const unsigned char tmp_ipq_packet[] = "\xA0\x85\x07\x12\x00\x88\xFF\xFF\x00\x00"
43 "\x00\x00\x00\x00\x00\x00\xD3\x98\x81\x4E\x00\x00\x00\x00\x27\x21\x0D"
44 "\x00\x00\x00\x00\x00\x02\x00\x00\x00\x65\x74\x68\x31\x00\x00\x00\x00"
45 "\x00\x00\x00\x00\x00\x00\x00\x00\x65\x74\x68\x32\x00\x00\x00\x00\x00"
46 "\x00\x00\x00\x00\x00\x00\x00\x08\x00\x01\x00\x06\x08\x00\x27\x45\x4D"
47 "\x26\x00\x00\x00\x00\x00\x00\x00\x00\x00\xA0\x02\x00\x00\x00\x00\x00"
48 "\x00\x45\x00\x02\xA0\x00\x00\x40\x00\x3F\x11\xB3\xEF\xC0\xA8\x01\x0A"
49 "\xC0\xA8\x03\x03\x29\x04\x29\x04\x02\x8C\x00\x00\x00\x00\x00\x00\x3B"
50 "\x4F\x03\x11\x00\x00\x00\x00\x20\x01\x00\x1B\xD8\xB0\x77\xF0\xC6\x17"
51 "\x71\x70\xDE\xD7\xF3\x20\x20\x01\x00\x17\x5D\xF8\xC4\x26\x98\xE5\x5F"
52 "\xA2\x28\x6D\x28\x47\x00\x41\x00\x0C\x00\x00\x00\x48\x00\x00\x00\x00"
53 "\x2D\x4A\x07\x08\x01\x41\x00\x14\x00\x00\x48\x49\x90\x7D\xD8\x95\x84"
54 "\xB3\x8D\xDC\x18\x25\xF9\x65\xE3\x31\x3E\xDD\x01\x42\x00\x1C\x01\x02"
55 "\x82\xEC\x42\x00\x00\x00\x00\x00\x5A\x3C\x03\x14\x9A\x0E\x9D\xCA\xF0"
56 "\x19\xAD\x2B\xBA\x43\x33\x66\xF8\xB2\x02\x01\x00\xC3\x03\x00\xC0\x7C"
57 "\xDA\x02\x1F\xB7\xFE\x85\xBB\xD1\x93\xFD\xB2\xFB\xC0\xB1\xAD\x09\x61"
58 "\x1F\x8E\xDD\x8F\x1B\xFC\xC3\x97\xA1\xCE\x4C\x55\x85\xB4\x4A\x8B\x66"
59 "\x93\x2A\xDF\x85\xC0\x3A\x84\xA2\x22\x4F\xB3\xF9\x6F\xC5\x54\x23\x9D"
60 "\xC2\x03\xEB\xB9\x55\xA4\xF0\x19\xC0\x2B\x4C\xD1\xBF\xC9\x04\xF5\x32"
61 "\xAB\x39\xEF\x7B\xF9\xA7\xAB\x5A\xC5\x27\x5E\x21\x83\x48\xB0\x8E\x19"
62 "\xB4\x51\x2B\xBA\x79\x00\x62\x70\x48\xF3\x44\xAE\x49\xD4\xC9\x20\x74"
63 "\x38\x0D\x11\xCA\xB3\x6F\x03\x47\x9A\x39\xA5\xFB\xC0\x70\xD6\xB5\xB6"
64 "\x35\x08\xB4\xB0\x33\x19\xF9\x07\x3C\x82\x7D\x3C\x16\x0C\x74\x9A\x1F"
65 "\x9B\xB2\xE6\xB3\xC7\xB3\x08\xE2\x10\x66\x23\x95\xF6\x00\xC7\x57\x8B"
66 "\x19\x83\x9E\x6F\xB6\x9D\x6A\x44\x25\xF1\xFD\x45\xFB\xD4\xD9\xE8\xA7"
67 "\xD5\xF9\xA7\xA5\xFB\xA3\x23\xD2\xDE\x67\x15\x9C\x6C\xFB\x5B\x08\xAC"
68 "\x7F\xC9\xF9\xD7\x00\x02\x41\x00\x02\x00\x01\x00\x00\x02\xC1\x00\x92"
69 "\x00\x88\x10\x06\x02\x02\xFF\x05\x03\x01\x00\x01\xD6\xBD\x7C\x86\xC3"
70 "\x4A\xA3\x93\x7F\xD9\x82\xBD\x22\xF1\xC7\x4F\x72\x76\x4F\x2F\x68\xF7"
71 "\x4F\x9D\xCE\xF3\xAE\xD4\x3B\x13\x5D\xC1\xF7\xF8\x09\x4E\xB4\xCD\x82"
72 "\x6F\xF8\xD1\x70\x01\x4E\xC0\x64\x82\xF1\x7E\x21\x54\x62\x73\x08\xEA"
73 "\x0A\x66\x1B\xA7\x9A\x4A\xAA\x17\x56\x77\x1D\x4D\x0D\xD2\x19\x92\xA0"
74 "\xAC\xF7\x23\x62\xE2\xF0\xFB\x1E\x73\x19\x16\x61\x1B\x85\x02\x42\x4B"
75 "\x89\x46\x09\x71\x42\x6F\x40\x8E\x62\x31\xA6\x4F\x17\x45\xF2\x7B\xFA"
76 "\xF2\xB6\xC8\x87\x37\x3A\xDF\xBB\x10\xE8\xDA\x97\x31\x6C\x38\xDF\xD0"
77 "\x97\x45\x84\x39\x61\x6C\x69\x63\x65\x00\x00\x00\x0F\xFF\x00\x04\x00"
78 "\x00\x00\x01\xF0\x41\x00\x14\xE7\x35\x6F\x89\x30\x3E\x1E\xA7\xFB\x93"
79 "\x8B\xBE\xD1\x34\x1F\x35\xB8\xE0\x82\x0C\xF1\x01\x00\x81\x05\xA6\xA2"
80 "\x75\xEF\xA8\xC3\x9C\x64\x9E\x9A\xDA\xFB\x38\xB4\x05\x8C\x6A\x6E\x5B"
81 "\x59\x9F\x11\x5B\xA6\xC0\x05\x42\xA6\x0D\x9C\x62\x17\x0E\x23\xB6\x3B"
82 "\x15\xB8\xEC\x6F\xE3\xB6\x6E\x80\x76\x97\xBE\x5B\x5B\x1A\x90\x30\xDF"
83 "\x1F\x32\x2C\x4E\x22\x20\x0B\xD4\x2B\x5B\x7C\xEF\x27\xEA\xB9\x80\x27"
84 "\xEF\xBC\xB4\xAF\x97\x2A\xD5\x86\xDA\xEE\x2C\xF0\x8B\x45\x00\x10\xE1"
85 "\x3A\x95\x35\xAC\x7C\xA8\x88\xC1\x60\xB9\x71\xD3\xE2\x29\xF7\x75\xD0"
86 "\x7E\x27\x1B\x21\x43\xAE\xBB\x08\xE1\x6B\x9E\x1E\xB9\x55\x89\xE3\x2B"
87 "\x29\x06\x4A\xA2\x90\x98\x38\x00\x00\x00";
88static const uint8_t opaque[] = "\x01\x41\x01\x14\x05\x00\x48\x49\x0b"
89 "\x02\x42\x02\x15\x06\x08\x49\x50\x0c";
90
91START_TEST(hipfw_splice_param_correct)
92{
93 struct hip_fw_context ctx;
94 struct hip_common *tmp_msg = NULL;
95 const struct hip_tlv_common *param = NULL;
96
97 mock_ipq = true;
98 mock_ipq_pkt_len = ARRAY_SIZE(tmp_ipq_packet);
99
100 fail_unless(hip_fw_init_context(&ctx, tmp_ipq_packet, 4) == 0, NULL);
101
102 tmp_msg = hip_msg_alloc();
103 hip_build_param_challenge_request(tmp_msg, 0, 0, opaque,
104 MIDAUTH_DEFAULT_NONCE_LENGTH);
105 param = hip_get_param(tmp_msg, HIP_PARAM_CHALLENGE_REQUEST);
106
107 fail_unless(hipfw_splice_param(&ctx, param) == true, NULL);
108}
109END_TEST
110
111#ifdef HAVE_TCASE_ADD_EXIT_TEST
112START_TEST(hipfw_splice_param_NULL_ctx)
113{
114 struct hip_common *tmp_msg = NULL;
115 const struct hip_tlv_common *param = NULL;
116
117 tmp_msg = hip_msg_alloc();
118 hip_build_param_challenge_request(tmp_msg, 0, 0, opaque,
119 MIDAUTH_DEFAULT_NONCE_LENGTH);
120 param = hip_get_param(tmp_msg, HIP_PARAM_CHALLENGE_REQUEST);
121
122 fail_unless(hipfw_splice_param(NULL, param) == false, NULL);
123}
124END_TEST
125
126START_TEST(hipfw_splice_param_NULL_param)
127{
128 struct hip_fw_context ctx;
129
130 mock_ipq = true;
131 mock_ipq_pkt_len = ARRAY_SIZE(tmp_ipq_packet);
132
133 fail_unless(hip_fw_init_context(&ctx, tmp_ipq_packet, 4) == 0, NULL);
134 fail_unless(hipfw_splice_param(&ctx, NULL) == false, NULL);
135}
136END_TEST
137#endif
138
139Suite *firewall_rewrite(void)
140{
141 Suite *s = suite_create("firewall/rewrite");
142 TCase *tc_rewrite = tcase_create("rewrite");
143 tcase_add_test(tc_rewrite, hipfw_splice_param_correct);
144#ifdef HAVE_TCASE_ADD_EXIT_TEST
145 tcase_add_exit_test(tc_rewrite, hipfw_splice_param_NULL_ctx, 1);
146 tcase_add_exit_test(tc_rewrite, hipfw_splice_param_NULL_param, 1);
147#endif
148 suite_add_tcase(s, tc_rewrite);
149
150 return s;
151}
0152
=== modified file 'test/firewall/test_suites.h'
--- test/firewall/test_suites.h 2011-04-04 16:36:55 +0000
+++ test/firewall/test_suites.h 2011-10-25 12:58:23 +0000
@@ -32,6 +32,8 @@
32Suite *firewall_file_buffer(void);32Suite *firewall_file_buffer(void);
33Suite *firewall_helpers(void);33Suite *firewall_helpers(void);
34Suite *firewall_line_parser(void);34Suite *firewall_line_parser(void);
35Suite *firewall_midauth(void);
35Suite *firewall_port_bindings(void);36Suite *firewall_port_bindings(void);
37Suite *firewall_rewrite(void);
3638
37#endif /* HIP_TEST_FIREWALL_TEST_SUITES_H */39#endif /* HIP_TEST_FIREWALL_TEST_SUITES_H */
3840
=== modified file 'test/mocks.c'
--- test/mocks.c 2011-08-15 14:11:56 +0000
+++ test/mocks.c 2011-10-25 12:58:23 +0000
@@ -87,6 +87,7 @@
87#include <stdlib.h>87#include <stdlib.h>
88#include <string.h>88#include <string.h>
89#include <time.h>89#include <time.h>
90#include <libipq.h>
9091
91#include "mocks.h"92#include "mocks.h"
9293
@@ -189,3 +190,28 @@
189190
190 return EXIT_SUCCESS;191 return EXIT_SUCCESS;
191}192}
193
194/*** ipq_get_packet(3) ***/
195bool mock_ipq = false;
196unsigned int mock_ipq_pkt_len = 0;
197
198/**
199 * ipq_get_packet(3) mock function. Controlled by the ::mock_ipq flag.
200 *
201 * @param buf contents of the returned ipq_packet_msg_t
202 * @return a fully filled ipq_packet_msg_t
203 *
204 * @note The buffer length is required for this mock function. You can provide
205 * it via the ::mock_ipq_pkt_len flag.
206 */
207ipq_packet_msg_t *ipq_get_packet(const unsigned char *buf)
208{
209 if (!mock_ipq) {
210 ipq_packet_msg_t *(*original)(const unsigned char *) = get_original(ipq_get_packet, "ipq_get_packet");
211 return original(buf);
212 } else {
213 char *tmp = malloc(mock_ipq_pkt_len);
214 memcpy(tmp, buf, mock_ipq_pkt_len);
215 return (ipq_packet_msg_t *) tmp;
216 }
217}
192218
=== modified file 'test/mocks.h'
--- test/mocks.h 2011-04-06 20:27:16 +0000
+++ test/mocks.h 2011-10-25 12:58:23 +0000
@@ -36,4 +36,7 @@
36extern bool mock_system;36extern bool mock_system;
37extern char *mock_system_last;37extern char *mock_system_last;
3838
39extern bool mock_ipq;
40extern unsigned int mock_ipq_pkt_len;
41
39#endif /* HIP_TEST_MOCKS_H */42#endif /* HIP_TEST_MOCKS_H */

Subscribers

People subscribed via source and target branches