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