Re: [Users] Problems with selectors patch and automatic %hold eroutes

From: Andreas Steffen (andreas.steffen_at_strongsec.net)
Date: Tue Dec 31 2002 - 16:33:54 CET


I have started to analyze the recorded error.

    Dec 31 11:43:45 firewall pluto[27222]
    : | *received pfkey message

1) pfkey_event() detects outbound activity and calls pfkey_get()
    adn pfkey_async()

    : | pfkey_get: SADB_ACQUIRE message 1

2) pfkey_async() calls pfkey_aquire()

    : | pfkey_async: SADB_ACQUIRE len=29, errno=0, satype=3, seq=1, pid=0

3) pfkey_aquire() calls record_and_initiate_opportunistic(&ours, &his)
    (note: must check if port and protocol information is extracted and
     available to record_and_initiate_opportunistic()).

4) record_and_initiate_opportunistic() creates a bare_shunt without
    port and protocol information and calls initiate_opportunistic().

    : | add bare shunt 0x80d2508 160.85.106.4/32 -> 160.85.196.15/32 => %hold

5) initiate_opportunistic() calls initiate_opportunistic_body().

    : | initiate on demand from 160.85.106.4 to 160.85.196.15

6) initiate_opportunistic_body() calls find_connection_for_clients()
    to select a matching connection. Unfortunately port and protocol
    selectors are not taken into account. This is the reason that
    the wrong connection is chosen (https instead of imaps).

7) initiate_opportunistic_body() then calls assign_hold() which
    calls replace_bare_shunt(). the transport_proto parameter of
    replace_bare_shunt() becomes c->protocol, which might turn out
    wrong when find_connection_for_clients() chooses a connection
    with the wrong protocol (my 0.0.0.0/0 setup I wrote about
    first, has three connections for udp, tcp, and icmp, respectively.
    When I put down the udp IPsec SA, then find_client_connection() will
    choose the icmp IPsec SA).

8) replace_bare_shunt() calls raw_eroute() which tries to delete the
    %hold eroute.

    : | delete narrow %hold eroute 160.85.106.4/32:0 -> 160.85.196.15/32:0
                                                                => %hold:6

     : | finish_pfkey_msg: SADB_X_DELFLOW message 113 for flow %hold
     : | 02 0f 00 0b 0f 00 00 00 71 00 00 00 56 6a 00 00
     : | 03 00 15 00 00 00 00 00 02 00 00 00 a0 55 6a 04
     : | 7c e5 ff bf e8 e4 ff bf 03 00 16 00 00 00 00 00
     : | 02 00 00 00 a0 55 c4 0f 58 f6 ff bf b7 28 0e 40
     : | 03 00 17 00 00 00 00 00 02 00 00 00 ff ff ff ff
     : | 1f 00 00 00 0b 00 00 00 03 00 18 00 00 00 00 00
     : | 02 00 00 00 ff ff ff ff 07 00 00 00 e1 fa 08 08
     : | 01 00 1a 00 06 22 00 00
     : ERROR: pfkey write() of SADB_X_DELFLOW message 113 for flow %hold failed.
                                                          Errno 14: Bad address

     This fails. Why? Probably because no port information is transmitted
     in the pfkey_message???

9) initiate_oppportunistic_body() next calls ipsecdoi_initiate() which in
    turn starts quick_outI1()

    : | duplicating state object #1
    : | creating state object #17 at 0x80d20a8
    : | ICOOKIE: d0 f5 e8 05 b4 ff 1d e7
    : | RCOOKIE: 5e ee 03 f6 dc 97 94 e5
    : | peer: a0 55 8b f0
    : | state hash entry 26
    : | inserting event EVENT_SO_DISCARD, timeout in 0 seconds for #17
    : "strongsec-zhw-mail-https" #17: initiating Quick Mode
                                       RSASIG+ENCRYPT+TUNNEL+PFS

Proposed fixes:

- find_connection_for_clients() must take into account port and
   protocol selectors, so that the correct connection is chosen.

- The bare_shunt mechanism must be made aware of port and protocol
    selectors, so that the %hold eroutes can be deleted correctly.

I appended the source code of all the functions I mentioned above
to the log file.

Regards

Andreas

======================================================================
Andreas Steffen e-mail: andreas.steffen_at_strongsec.com
strongSec GmbH phone: +41 76 340 25 56
Alter Zürichweg 20 home: http://www.strongsec.com
CH-8952 Schlieren (Switzerland)
==========================================[strong internet security]==

Dec 31 11:42:47 firewall pluto[27222]: | *received whack message
Dec 31 11:42:47 firewall pluto[27222]: "strongsec-zhw-mail-imaps": terminating SAs using this connection
Dec 31 11:42:47 firewall pluto[27222]: "strongsec-zhw-mail-imaps" #7: deleting state (STATE_QUICK_I2)
Dec 31 11:42:47 firewall pluto[27222]: | executing down-client: 2>&1 PLUTO_VERSION='1.1' PLUTO_VERB='down-client' PLUTO_CONNECTION='strongsec-zhw-mail-imaps' PL
UTO_NEXT_HOP='80.218.56.1' PLUTO_INTERFACE='ipsec0' PLUTO_ME='80.218.56.160' PLUTO_MY_ID='sna_at_zhwin.ch' PLUTO_MY_CLIENT='160.85.106.0/28' PLUTO_MY_CLIENT_NET='1
60.85.106.0' PLUTO_MY_CLIENT_MASK='255.255.255.240' PLUTO_MY_PORT='0' PLUTO_MY_PROTOCOL='6' PLUTO_PEER='160.85.139.240' PLUTO_PEER_ID='@pluto.zhwin.ch' PLUTO_PE
ER_CLIENT='160.85.196.15/32' PLUTO_PEER_CLIENT_NET='160.85.196.15' PLUTO_PEER_CLIENT_MASK='255.255.255.255' PLUTO_PEER_PORT='993' PLUTO_PEER_PROTOCOL='6' /usr/l
ocal/lib/ipsec/updown
Dec 31 11:42:47 firewall vpn: - @pluto.zhwin.ch 160.85.196.15/32 == 160.85.139.240 -- 80.218.56.160 == 160.85.106.0/28
Dec 31 11:42:47 firewall pluto[27222]: | replace with shunt eroute 160.85.106.0/28:0 -> 160.85.196.15/32:993 => %trap:6
Dec 31 11:42:47 firewall pluto[27222]: | finish_pfkey_msg: SADB_X_ADDFLOW message 110 for flow %trap
Dec 31 11:42:47 firewall pluto[27222]: | 02 0e 00 0b 17 00 00 00 6e 00 00 00 56 6a 00 00
Dec 31 11:42:47 firewall pluto[27222]: | 02 00 01 00 00 00 01 04 00 00 00 00 02 00 00 00
Dec 31 11:42:47 firewall pluto[27222]: | 03 00 05 00 00 00 00 00 02 00 00 00 50 da 38 a0
Dec 31 11:42:47 firewall pluto[27222]: | 00 00 00 00 00 00 00 00 03 00 06 00 00 00 00 00
Dec 31 11:42:47 firewall pluto[27222]: | 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Dec 31 11:42:47 firewall pluto[27222]: | 03 00 15 00 00 00 00 00 02 00 00 00 a0 55 6a 00
Dec 31 11:42:47 firewall pluto[27222]: | 74 f4 ff bf 0c f4 ff bf 03 00 16 00 00 00 00 00
Dec 31 11:42:47 firewall pluto[27222]: | 02 00 03 e1 a0 55 c4 0f 0c eb ff bf 0c eb ff bf
Dec 31 11:42:47 firewall pluto[27222]: | 03 00 17 00 00 00 00 00 02 00 00 00 ff ff ff f0
Dec 31 11:42:47 firewall pluto[27222]: | 00 00 00 00 00 00 00 00 03 00 18 00 00 00 00 00
Dec 31 11:42:47 firewall pluto[27222]: | 02 00 ff ff ff ff ff ff 00 00 00 00 00 00 00 00
Dec 31 11:42:47 firewall pluto[27222]: | 01 00 1a 00 06 22 00 00
Dec 31 11:42:47 firewall pluto[27222]: | pfkey_get: SADB_X_ADDFLOW message 110
Dec 31 11:42:47 firewall pluto[27222]: | delete esp.924cba49_at_160.85.139.240
Dec 31 11:42:47 firewall pluto[27222]: | finish_pfkey_msg: SADB_DELETE message 111 for Delete SA esp.924cba49_at_160.85.139.240
Dec 31 11:42:47 firewall pluto[27222]: | 02 04 00 03 0a 00 00 00 6f 00 00 00 56 6a 00 00
Dec 31 11:42:47 firewall pluto[27222]: | 02 00 01 00 92 4c ba 49 00 01 00 00 00 00 00 00
Dec 31 11:42:47 firewall pluto[27222]: | 03 00 05 00 00 00 00 00 02 00 00 00 50 da 38 a0
Dec 31 11:42:47 firewall pluto[27222]: | 00 00 00 00 00 00 00 00 03 00 06 00 00 00 00 00
Dec 31 11:42:47 firewall pluto[27222]: | 02 00 03 e1 a0 55 8b f0 00 00 00 00 00 00 00 00
Dec 31 11:42:47 firewall pluto[27222]: | pfkey_get: SADB_DELETE message 111
Dec 31 11:42:47 firewall pluto[27222]: | delete esp.b5a9d5d_at_80.218.56.160
Dec 31 11:42:47 firewall pluto[27222]: | finish_pfkey_msg: SADB_DELETE message 112 for Delete SA esp.b5a9d5d_at_80.218.56.160
Dec 31 11:42:47 firewall pluto[27222]: | 02 04 00 03 0a 00 00 00 70 00 00 00 56 6a 00 00
Dec 31 11:42:47 firewall pluto[27222]: | 02 00 01 00 0b 5a 9d 5d 00 01 00 00 00 00 00 00
Dec 31 11:42:47 firewall pluto[27222]: | 03 00 05 00 00 00 00 00 02 00 03 e1 a0 55 8b f0
Dec 31 11:42:47 firewall pluto[27222]: | 00 00 00 00 00 00 00 00 03 00 06 00 00 00 00 00
Dec 31 11:42:47 firewall pluto[27222]: | 02 00 00 00 50 da 38 a0 00 00 00 00 00 00 00 00
Dec 31 11:42:47 firewall pluto[27222]: | pfkey_get: SADB_DELETE message 112
Dec 31 11:42:47 firewall pluto[27222]: | next event EVENT_SHUNT_SCAN in 13 seconds
Dec 31 11:42:47 firewall pluto[27222]: |
Dec 31 11:42:47 firewall pluto[27222]: | *received 76 bytes from 160.85.139.240:500 on eth0
Dec 31 11:42:47 firewall pluto[27222]: | ICOOKIE: d0 f5 e8 05 b4 ff 1d e7
Dec 31 11:42:47 firewall pluto[27222]: | RCOOKIE: 5e ee 03 f6 dc 97 94 e5
Dec 31 11:42:47 firewall pluto[27222]: | peer: a0 55 8b f0
Dec 31 11:42:47 firewall pluto[27222]: | state hash entry 26
Dec 31 11:42:47 firewall pluto[27222]: | state object #1 found, in STATE_MAIN_I4
Dec 31 11:42:47 firewall pluto[27222]: "strongsec-pluto" #1: ignoring Delete SA payload: IPSEC SA not found (maybe expired)
Dec 31 11:42:47 firewall pluto[27222]: | next event EVENT_SHUNT_SCAN in 13 seconds
Dec 31 11:43:00 firewall pluto[27222]: |
Dec 31 11:43:00 firewall pluto[27222]: | *time to handle event
Dec 31 11:43:00 firewall pluto[27222]: | event after this is EVENT_SA_REPLACE in 2438 seconds
Dec 31 11:43:00 firewall pluto[27222]: | inserting event EVENT_SHUNT_SCAN, timeout in 120 seconds
Dec 31 11:43:00 firewall pluto[27222]: | next event EVENT_SHUNT_SCAN in 120 seconds
Dec 31 11:43:20 firewall kernel: IN: IN=eth0 OUT= MAC=00:e0:29:20:5a:83:00:09:7b:8c:38:70:08:00 SRC=202.157.74.53 DST=80.218.56.160 LEN=78 TOS=0x00 PREC=0x00 TT
L=113 ID=6020 PROTO=UDP SPT=1026 DPT=137 LEN=58
Dec 31 11:43:45 firewall pluto[27222]: |
Dec 31 11:43:45 firewall pluto[27222]: | *received pfkey message
Dec 31 11:43:45 firewall pluto[27222]: | pfkey_get: SADB_ACQUIRE message 1
Dec 31 11:43:46 firewall pluto[27222]: | pfkey_async: SADB_ACQUIRE len=29, errno=0, satype=3, seq=1, pid=0
Dec 31 11:43:46 firewall pluto[27222]: | add bare shunt 0x80d2508 160.85.106.4/32 -> 160.85.196.15/32 => %hold
Dec 31 11:43:46 firewall pluto[27222]: | initiate on demand from 160.85.106.4 to 160.85.196.15
Dec 31 11:43:46 firewall pluto[27222]: | delete narrow %hold eroute 160.85.106.4/32:0 -> 160.85.196.15/32:0 => %hold:6
Dec 31 11:43:46 firewall pluto[27222]: | finish_pfkey_msg: SADB_X_DELFLOW message 113 for flow %hold
Dec 31 11:43:46 firewall pluto[27222]: | 02 0f 00 0b 0f 00 00 00 71 00 00 00 56 6a 00 00
Dec 31 11:43:46 firewall pluto[27222]: | 03 00 15 00 00 00 00 00 02 00 00 00 a0 55 6a 04
Dec 31 11:43:46 firewall pluto[27222]: | 7c e5 ff bf e8 e4 ff bf 03 00 16 00 00 00 00 00
Dec 31 11:43:46 firewall pluto[27222]: | 02 00 00 00 a0 55 c4 0f 58 f6 ff bf b7 28 0e 40
Dec 31 11:43:46 firewall pluto[27222]: | 03 00 17 00 00 00 00 00 02 00 00 00 ff ff ff ff
Dec 31 11:43:46 firewall pluto[27222]: | 1f 00 00 00 0b 00 00 00 03 00 18 00 00 00 00 00
Dec 31 11:43:46 firewall pluto[27222]: | 02 00 00 00 ff ff ff ff 07 00 00 00 e1 fa 08 08
Dec 31 11:43:46 firewall pluto[27222]: | 01 00 1a 00 06 22 00 00
Dec 31 11:43:46 firewall pluto[27222]: ERROR: pfkey write() of SADB_X_DELFLOW message 113 for flow %hold failed. Errno 14: Bad address
Dec 31 11:43:46 firewall pluto[27222]: | duplicating state object #1
Dec 31 11:43:46 firewall pluto[27222]: | creating state object #17 at 0x80d20a8
Dec 31 11:43:46 firewall pluto[27222]: | ICOOKIE: d0 f5 e8 05 b4 ff 1d e7
Dec 31 11:43:46 firewall pluto[27222]: | RCOOKIE: 5e ee 03 f6 dc 97 94 e5
Dec 31 11:43:46 firewall pluto[27222]: | peer: a0 55 8b f0
Dec 31 11:43:46 firewall pluto[27222]: | state hash entry 26
Dec 31 11:43:46 firewall pluto[27222]: | inserting event EVENT_SO_DISCARD, timeout in 0 seconds for #17
Dec 31 11:43:46 firewall pluto[27222]: "strongsec-zhw-mail-https" #17: initiating Quick Mode RSASIG+ENCRYPT+TUNNEL+PFS
Dec 31 11:43:46 firewall pluto[27222]: | 12_128-1, 12_128-2, 3_000-1, 3_000-2, flags=-strict
Dec 31 11:43:46 firewall pluto[27222]: | kernel_alg_db_prop_new() will return p_new->protoid=3, p_new->trans_cnt=4
Dec 31 11:43:46 firewall pluto[27222]: | kernel_alg_db_prop_new() trans[0]: transid=12, attr_cnt=2, attrs[0].type=5, attrs[0].val=1
Dec 31 11:43:46 firewall pluto[27222]: | kernel_alg_db_prop_new() trans[1]: transid=12, attr_cnt=2, attrs[0].type=5, attrs[0].val=2
Dec 31 11:43:46 firewall pluto[27222]: | kernel_alg_db_prop_new() trans[2]: transid=3, attr_cnt=1, attrs[0].type=5, attrs[0].val=1
Dec 31 11:43:46 firewall pluto[27222]: | kernel_alg_db_prop_new() trans[3]: transid=3, attr_cnt=1, attrs[0].type=5, attrs[0].val=2
Dec 31 11:43:46 firewall pluto[27222]: | generate SPI: 0b 5a 9d 65
Dec 31 11:43:46 firewall pluto[27222]: | inserting event EVENT_RETRANSMIT, timeout in 10 seconds for #17
Dec 31 11:43:46 firewall pluto[27222]: | next event EVENT_RETRANSMIT in 10 seconds for #17
Dec 31 11:43:46 firewall pluto[27222]: |
Dec 31 11:43:46 firewall pluto[27222]: | *received pfkey message
Dec 31 11:43:46 firewall pluto[27222]: | pfkey_get: SADB_X_DELFLOW message 113
Dec 31 11:43:46 firewall pluto[27222]: | pfkey_async: SADB_X_DELFLOW len=2, errno=14, satype=11, seq=113, pid=27222
Dec 31 11:43:46 firewall pluto[27222]: | next event EVENT_RETRANSMIT in 10 seconds for #17
Dec 31 11:43:46 firewall pluto[27222]: |
Dec 31 11:43:46 firewall pluto[27222]: | *received 364 bytes from 160.85.139.240:500 on eth0
Dec 31 11:43:46 firewall pluto[27222]: | ICOOKIE: d0 f5 e8 05 b4 ff 1d e7
Dec 31 11:43:46 firewall pluto[27222]: | RCOOKIE: 5e ee 03 f6 dc 97 94 e5
Dec 31 11:43:46 firewall pluto[27222]: | peer: a0 55 8b f0
Dec 31 11:43:46 firewall pluto[27222]: | state hash entry 26
Dec 31 11:43:46 firewall pluto[27222]: | state object #17 found, in STATE_QUICK_I1
Dec 31 11:43:46 firewall pluto[27222]: | kernel_alg_esp_enc_ok(12,128): alg_id=12, alg_ivlen=128, alg_minbits=128, alg_maxbits=256, res=0, ret=1
Dec 31 11:43:46 firewall pluto[27222]: | kernel_alg_esp_auth_ok(auth=1): ret=1
Dec 31 11:43:46 firewall pluto[27222]: | our client is subnet 160.85.106.0/28
Dec 31 11:43:46 firewall pluto[27222]: | our client protocol/port is 6/0
Dec 31 11:43:46 firewall pluto[27222]: | peer client is subnet 160.85.196.15/32
Dec 31 11:43:46 firewall pluto[27222]: | peer client protocol/port is 6/443
Dec 31 11:43:46 firewall pluto[27222]: | kernel_alg_esp_enc_keylen():alg_id=12, keylen=32
Dec 31 11:43:46 firewall pluto[27222]: | kernel_alg_esp_auth_ok(auth=1): ret=1
Dec 31 11:43:46 firewall pluto[27222]: | kernel_alg_esp_auth_keylen(auth=1, sadb_aalg=2): a_keylen=16
Dec 31 11:43:46 firewall pluto[27222]: | route owner of "strongsec-zhw-mail-https" CK_PERMANENT erouted: self; eroute owner: self
Dec 31 11:43:46 firewall pluto[27222]: | finish_pfkey_msg: SADB_ADD message 114 for Add ESP SA esp.b5a9d65_at_80.218.56.160
Dec 31 11:43:46 firewall pluto[27222]: | 02 03 00 03 10 00 00 00 72 00 00 00 56 6a 00 00
Dec 31 11:43:46 firewall pluto[27222]: | 02 00 01 00 0b 5a 9d 65 40 01 02 0c 00 00 00 00
Dec 31 11:43:46 firewall pluto[27222]: | 03 00 05 00 00 00 00 00 02 00 01 bb a0 55 8b f0
Dec 31 11:43:46 firewall pluto[27222]: | 00 00 00 00 00 00 00 00 03 00 06 00 00 00 00 00
Dec 31 11:43:46 firewall pluto[27222]: | 02 00 00 00 50 da 38 a0 00 00 00 00 00 00 00 00
Dec 31 11:43:46 firewall pluto[27222]: | 03 00 08 00 80 00 00 00 e5 b3 f4 8d a1 10 31 35
Dec 31 11:43:46 firewall pluto[27222]: | ed 35 27 dd 4c d0 cc 13 03 00 09 00 80 00 00 00
Dec 31 11:43:46 firewall pluto[27222]: | 57 d6 c0 9a 53 c7 c3 b2 4b 90 28 95 04 38 9e ab
Dec 31 11:43:46 firewall pluto[27222]: | pfkey_get: SADB_ADD message 114
Dec 31 11:43:46 firewall pluto[27222]: | finish_pfkey_msg: SADB_ADD message 115 for Add IPIP SA tun.1019_at_160.85.139.240
Dec 31 11:43:46 firewall pluto[27222]: | 02 03 00 09 0a 00 00 00 73 00 00 00 56 6a 00 00
Dec 31 11:43:46 firewall pluto[27222]: | 02 00 01 00 00 00 10 19 00 01 00 00 00 00 00 00
Dec 31 11:43:46 firewall pluto[27222]: | 03 00 05 00 00 00 00 00 02 00 01 bb a0 55 8b f0
Dec 31 11:43:46 firewall pluto[27222]: | 00 00 00 00 00 00 00 00 03 00 06 00 00 00 00 00
Dec 31 11:43:46 firewall pluto[27222]: | 02 00 00 00 50 da 38 a0 00 00 00 00 00 00 00 00
Dec 31 11:43:46 firewall pluto[27222]: | pfkey_get: SADB_ADD message 115
Dec 31 11:43:46 firewall pluto[27222]: | add inbound eroute 160.85.196.15/32:0 -> 160.85.106.0/28:0 => tun.1019_at_80.218.56.160:0
Dec 31 11:43:46 firewall pluto[27222]: | finish_pfkey_msg: SADB_X_ADDFLOW message 116 for flow tun.1019_at_80.218.56.160
Dec 31 11:43:46 firewall pluto[27222]: | 02 0e 00 09 16 00 00 00 74 00 00 00 56 6a 00 00
Dec 31 11:43:46 firewall pluto[27222]: | 02 00 01 00 00 00 10 19 00 00 00 00 08 00 00 00
Dec 31 11:43:46 firewall pluto[27222]: | 03 00 05 00 00 00 00 00 02 00 01 bb a0 55 8b f0
Dec 31 11:43:46 firewall pluto[27222]: | 00 00 00 00 00 00 00 00 03 00 06 00 00 00 00 00
Dec 31 11:43:46 firewall pluto[27222]: | 02 00 00 00 50 da 38 a0 00 00 00 00 00 00 00 00
Dec 31 11:43:46 firewall pluto[27222]: | 03 00 15 00 00 00 00 00 02 00 01 bb a0 55 c4 0f
Dec 31 11:43:46 firewall pluto[27222]: | 0c eb ff bf 0c eb ff bf 03 00 16 00 00 00 00 00
Dec 31 11:43:46 firewall pluto[27222]: | 02 00 00 00 a0 55 6a 00 74 f4 ff bf 0c f4 ff bf
Dec 31 11:43:46 firewall pluto[27222]: | 03 00 17 00 00 00 00 00 02 00 00 00 ff ff ff ff
Dec 31 11:43:46 firewall pluto[27222]: | 00 00 06 00 38 30 2e 32 03 00 18 00 00 00 00 00
Dec 31 11:43:46 firewall pluto[27222]: | 02 00 00 00 ff ff ff f0 00 00 00 00 a4 05 d5 9f
Dec 31 11:43:46 firewall pluto[27222]: | pfkey_get: SADB_X_ADDFLOW message 116
Dec 31 11:43:46 firewall pluto[27222]: | grouping tun.1019_at_80.218.56.160 and esp.b5a9d65_at_80.218.56.160
Dec 31 11:43:46 firewall pluto[27222]: | finish_pfkey_msg: SADB_X_GRPSA message 117 for group tun.1019_at_80.218.56.160
Dec 31 11:43:46 firewall pluto[27222]: | 02 0d 00 09 0d 00 00 00 75 00 00 00 56 6a 00 00
Dec 31 11:43:46 firewall pluto[27222]: | 02 00 01 00 00 00 10 19 00 00 00 00 00 00 00 00
Dec 31 11:43:46 firewall pluto[27222]: | 03 00 06 00 00 00 00 00 02 00 00 00 50 da 38 a0
Dec 31 11:43:46 firewall pluto[27222]: | 00 00 00 00 00 00 00 00 01 00 12 00 03 00 00 00
Dec 31 11:43:46 firewall pluto[27222]: | 02 00 13 00 0b 5a 9d 65 00 00 00 00 00 00 00 00
Dec 31 11:43:46 firewall pluto[27222]: | 03 00 14 00 00 00 00 00 02 00 00 00 50 da 38 a0
Dec 31 11:43:46 firewall pluto[27222]: | 00 00 00 00 00 00 00 00
Dec 31 11:43:46 firewall pluto[27222]: | pfkey_get: SADB_X_GRPSA message 117
Dec 31 11:43:46 firewall pluto[27222]: | finish_pfkey_msg: SADB_ADD message 118 for Add ESP SA esp.924cba4f_at_160.85.139.240
Dec 31 11:43:46 firewall pluto[27222]: | 02 03 00 03 10 00 00 00 76 00 00 00 56 6a 00 00
Dec 31 11:43:46 firewall pluto[27222]: | 02 00 01 00 92 4c ba 4f 40 01 02 0c 00 00 00 00
Dec 31 11:43:46 firewall pluto[27222]: | 03 00 05 00 00 00 00 00 02 00 00 00 50 da 38 a0
Dec 31 11:43:46 firewall pluto[27222]: | 00 00 00 00 00 00 00 00 03 00 06 00 00 00 00 00
Dec 31 11:43:46 firewall pluto[27222]: | 02 00 01 bb a0 55 8b f0 00 00 00 00 00 00 00 00
Dec 31 11:43:46 firewall pluto[27222]: | 03 00 08 00 80 00 00 00 eb 5d e0 9b 33 b3 e3 e4
Dec 31 11:43:46 firewall pluto[27222]: | bf 6f 14 f5 3a 71 82 7c 03 00 09 00 80 00 00 00
Dec 31 11:43:46 firewall pluto[27222]: | ee b4 38 cd ac fc 0c 1d c2 32 ce 3d 0f 42 c4 a4
Dec 31 11:43:46 firewall pluto[27222]: | pfkey_get: SADB_ADD message 118
Dec 31 11:43:46 firewall pluto[27222]: | finish_pfkey_msg: SADB_ADD message 119 for Add IPIP SA tun.101a_at_160.85.139.240
Dec 31 11:43:46 firewall pluto[27222]: | 02 03 00 09 0a 00 00 00 77 00 00 00 56 6a 00 00
Dec 31 11:43:46 firewall pluto[27222]: | 02 00 01 00 00 00 10 1a 00 01 00 00 00 00 00 00
Dec 31 11:43:46 firewall pluto[27222]: | 03 00 05 00 00 00 00 00 02 00 00 00 50 da 38 a0
Dec 31 11:43:46 firewall pluto[27222]: | 00 00 00 00 00 00 00 00 03 00 06 00 00 00 00 00
Dec 31 11:43:46 firewall pluto[27222]: | 02 00 01 bb a0 55 8b f0 00 00 00 00 00 00 00 00
Dec 31 11:43:46 firewall pluto[27222]: | pfkey_get: SADB_ADD message 119
Dec 31 11:43:46 firewall pluto[27222]: | grouping tun.101a_at_160.85.139.240 and esp.924cba4f_at_160.85.139.240
Dec 31 11:43:46 firewall pluto[27222]: | finish_pfkey_msg: SADB_X_GRPSA message 120 for group tun.101a_at_160.85.139.240
Dec 31 11:43:46 firewall pluto[27222]: | 02 0d 00 09 0d 00 00 00 78 00 00 00 56 6a 00 00
Dec 31 11:43:46 firewall pluto[27222]: | 02 00 01 00 00 00 10 1a 00 00 00 00 00 00 00 00
Dec 31 11:43:46 firewall pluto[27222]: | 03 00 06 00 00 00 00 00 02 00 01 bb a0 55 8b f0
Dec 31 11:43:46 firewall pluto[27222]: | 00 00 00 00 00 00 00 00 01 00 12 00 03 00 00 00
Dec 31 11:43:46 firewall pluto[27222]: | 02 00 13 00 92 4c ba 4f 00 00 00 00 00 00 00 00
Dec 31 11:43:46 firewall pluto[27222]: | 03 00 14 00 00 00 00 00 02 00 01 bb a0 55 8b f0
Dec 31 11:43:46 firewall pluto[27222]: | 00 00 00 00 00 00 00 00
Dec 31 11:43:46 firewall pluto[27222]: | pfkey_get: SADB_X_GRPSA message 120
Dec 31 11:43:46 firewall pluto[27222]: | route owner of "strongsec-zhw-mail-https" CK_PERMANENT erouted: self; eroute owner: self
Dec 31 11:43:46 firewall pluto[27222]: | replace eroute 160.85.106.0/28:0 -> 160.85.196.15/32:443 => tun.101a_at_160.85.139.240:6
Dec 31 11:43:46 firewall pluto[27222]: | finish_pfkey_msg: SADB_X_ADDFLOW message 121 for flow tun.101a_at_160.85.139.240
Dec 31 11:43:46 firewall pluto[27222]: | 02 0e 00 09 17 00 00 00 79 00 00 00 56 6a 00 00
Dec 31 11:43:46 firewall pluto[27222]: | 02 00 01 00 00 00 10 1a 00 00 00 00 02 00 00 00
Dec 31 11:43:46 firewall pluto[27222]: | 03 00 05 00 00 00 00 00 02 00 00 00 50 da 38 a0
Dec 31 11:43:46 firewall pluto[27222]: | 00 00 00 00 00 00 00 00 03 00 06 00 00 00 00 00
Dec 31 11:43:46 firewall pluto[27222]: | 02 00 01 bb a0 55 8b f0 00 00 00 00 00 00 00 00
Dec 31 11:43:46 firewall pluto[27222]: | 03 00 15 00 00 00 00 00 02 00 00 00 a0 55 6a 00
Dec 31 11:43:46 firewall pluto[27222]: | 74 f4 ff bf 0c f4 ff bf 03 00 16 00 00 00 00 00
Dec 31 11:43:46 firewall pluto[27222]: | 02 00 01 bb a0 55 c4 0f 0c eb ff bf 0c eb ff bf
Dec 31 11:43:46 firewall pluto[27222]: | 03 00 17 00 00 00 00 00 02 00 00 00 ff ff ff f0
Dec 31 11:43:46 firewall pluto[27222]: | 40 31 36 30 2e 38 35 2e 03 00 18 00 00 00 00 00
Dec 31 11:43:46 firewall pluto[27222]: | 02 00 ff ff ff ff ff ff c0 b2 0a 08 b0 e8 0c 08
Dec 31 11:43:46 firewall pluto[27222]: | 01 00 1a 00 06 22 00 00
Dec 31 11:43:46 firewall pluto[27222]: | pfkey_get: SADB_X_ADDFLOW message 121
Dec 31 11:43:46 firewall pluto[27222]: | inserting event EVENT_SA_REPLACE, timeout in 2948 seconds for #17
Dec 31 11:43:46 firewall pluto[27222]: "strongsec-zhw-mail-https" #17: sent QI2, IPsec SA established
Dec 31 11:43:46 firewall pluto[27222]: | next event EVENT_SHUNT_SCAN in 74 seconds
root_at_firewall:/var/log >

-----------------------------------------------------------------------------------------------

/* asynchronous messages directly from PF_KEY socket */
void
pfkey_event(void)
{
    pfkey_buf buf;

    if (pfkey_get(&buf))
        pfkey_async(&buf);
}

-----------------------------------------------------------------------------------------------

/* Handle PF_KEY messages from the kernel that are not dealt with
 * synchronously. In other words, all but responses to PF_KEY messages
 * that we sent.
 */
static void
pfkey_async(pfkey_buf *buf)
{
    struct sadb_ext *extensions[SADB_EXT_MAX + 1];

    if (pfkey_msg_parse(&buf->msg, NULL, extensions, EXT_BITS_OUT))
    {
        log("pfkey_async:"
            " unparseable PF_KEY message:"
            " %s len=%d, errno=%d, seq=%d, pid=%d; message ignored"
            , sparse_val_show(pfkey_type_names, buf->msg.sadb_msg_type)
            , buf->msg.sadb_msg_len
            , buf->msg.sadb_msg_errno
            , buf->msg.sadb_msg_seq
            , buf->msg.sadb_msg_pid);
    }
    else
    {
        DBG(DBG_CONTROL | DBG_KLIPS, DBG_log("pfkey_async:"
            " %s len=%u, errno=%u, satype=%u, seq=%u, pid=%u"
            , sparse_val_show(pfkey_type_names, buf->msg.sadb_msg_type)
            , buf->msg.sadb_msg_len
            , buf->msg.sadb_msg_errno
            , buf->msg.sadb_msg_satype
            , buf->msg.sadb_msg_seq
            , buf->msg.sadb_msg_pid));

        switch (buf->msg.sadb_msg_type)
        {
        case SADB_REGISTER:
            process_pfkey_register_response(buf);
            break;
        case SADB_ACQUIRE:
            /* to simulate loss of ACQUIRE, delete this call */
            process_pfkey_acquire(buf, extensions);
            break;
        default:
            /* ignored */
            break;
        }
    }
}

-----------------------------------------------------------------------------------------------

/* Processs a SADB_ACQUIRE message from KLIPS.
 * Try to build an opportunistic connection!
 * See RFC 2367 "PF_KEY Key Management API, Version 2" 3.1.6
 * <base, address(SD), (address(P)), (identity(SD),) (sensitivity,) proposal>
 * - extensions for source and data IP addresses
 * - optional extensions for identity [not useful for us?]
 * - optional extension for sensitivity [not useful for us?]
 * - expension for proposal [not useful for us?]
 *
 * ??? We must use the sequence number in creating an SA.
 * We actually need to create up to 4 SAs each way. Which one?
 * I guess it depends on the protocol present in the sadb_msg_satype.
 * For now, we'll ignore this requirement.
 *
 * ??? We need some mechanism to make sure that multiple ACQUIRE messages
 * don't cause a whole bunch of redundant negotiations.
 */
static void
process_pfkey_acquire(pfkey_buf *buf, struct sadb_ext *extensions[SADB_EXT_MAX + 1])
{
    struct sadb_address *srcx = (void *) extensions[SADB_EXT_ADDRESS_SRC];
    struct sadb_address *dstx = (void *) extensions[SADB_EXT_ADDRESS_DST];
    ip_address src, dst;
    ip_subnet ours, his;
    err_t ugh = NULL;

    /* assumption: we're only catching our own outgoing packets
     * so source is our end and destination is the other end.
     * Verifying this is not actually convenient.
     *
     * This stylized control structure yields a complaint or
     * desired results. For compactness, a pointer value is
     * treated as a boolean. Logically, the structure is:
     * keep going as long as things are OK.
     */
    if (buf->msg.sadb_msg_pid == 0 /* we only wish to hear from kernel */
    && !(ugh = sockaddr_to_ip_address((struct sockaddr *)(void *)&srcx[1], &src))
    && !(ugh = sockaddr_to_ip_address((struct sockaddr *)(void *)&dstx[1], &dst))
    && !(ugh = addrtypeof(&src) == addrtypeof(&dst)? NULL : "conflicting address types")
    && !(ugh = addrtosubnet(&src, &ours))
    && !(ugh = addrtosubnet(&dst, &his)))
        record_and_initiate_opportunistic(&ours, &his);

    if (ugh != NULL)
        log("SADB_ACQUIRE message from KLIPS malformed: %s", ugh);

}

-----------------------------------------------------------------------------------------------

static void
record_and_initiate_opportunistic(ip_subnet *ours, ip_subnet *his)
{
    passert(samesubnettype(ours, his));

    /* Add to bare shunt list.
     * We need to do this because the shunt was installed by KLIPS
     * which can't do this itself.
     */
    {
        struct bare_shunt *bs = alloc_thing(struct bare_shunt, "bare shunt");

        bs->ours = *ours;
        bs->his = *his;

        bs->said.proto = SA_INT;
        bs->said.spi = htonl(SPI_HOLD);
        bs->said.dst = *aftoinfo(subnettypeof(ours))->any;

        bs->count = 0;
        bs->last_activity = now();

        bs->next = bare_shunts;
        bare_shunts = bs;
        DBG_bare_shunt("add", bs);
    }

    /* actually initiate opportunism */
    {
        ip_address src, dst;

        networkof(ours, &src);
        networkof(his, &dst);
        initiate_opportunistic(&src, &dst, TRUE, NULL_FD);
    }

    /* if present, remove from orphaned_holds list.
     * NOTE: we do this last in case ours or his is a pointer into a member.
     */
    {
        struct eroute_info **pp, *p;

        for (pp = &orphaned_holds; (p = *pp) != NULL; pp = &p->next)
        {
            if (samesubnet(ours, &p->ours) && samesubnet(his, &p->his))
            {
                *pp = p->next;
                pfree(p);
                break;
            }
        }
    }
}

-----------------------------------------------------------------------------------------------

/* (Possibly) Opportunistic Initiation:
 * Knowing clients (single IP addresses), try to build an tunnel.
 * This may involve discovering a gateway and instantiating an
 * Opportunistic connection. Called when a packet is caught by
 * a %trap, or when whack --oppohere --oppothere is used.
 * It may turn out that an existing or non-opporunistic connnection
 * can handle the traffic.
 *
 * Most of the code will be restarted if an ADNS request is made
 * to discover the gateway. The only difference between the first
 * and second entry is whether gateways_from_dns is NULL or not.
 * initiate_opportunistic: initial entrypoint
 * continue_oppo: where we pickup when ADNS result arrives
 * initiate_opportunistic_body: main body shared by above routines
 * cannot_oppo: a helper function to log a diagnostic
 * This structure repeats a lot of code when the ADNS result arrives.
 * This seems like a waste, but anything learned the first time through
 * may no longer be true!
 *
 * After the first IKE message is sent, the regular state machinery
 * carries negotiation forward.
 */

void
initiate_opportunistic(const ip_address *our_client
, const ip_address *peer_client
, bool held
, int whackfd)
{
    passert(gateways_from_dns == NULL);
    initiate_opportunistic_body(our_client, peer_client, held, whackfd);
}

-----------------------------------------------------------------------------------------------

static void
initiate_opportunistic_body(const ip_address *our_client
, const ip_address *peer_client
, bool held
, int whackfd)
{
    struct connection *c;

    /* What connection shall we use?
     * First try for one that explicitly handles the clients.
     */
    DBG(DBG_CONTROL,
        {
            char ours[ADDRTOT_BUF];
            char his[ADDRTOT_BUF];

            addrtot(our_client, 0, ours, sizeof(ours));
            addrtot(peer_client, 0, his, sizeof(his));
            DBG_log("initiate on demand from %s to %s", ours, his);
        });

    c = find_connection_for_clients(our_client, peer_client);
    if (c != NULL)
    {
        /* We've found a connection that can serve.
         * Do we have to initiate it?
         * Not if there is currently an IPSEC SA.
         * But if there is an IPSEC SA, then KLIPS would not
         * have generated the acquire. So we assume that there isn't one.
         * This may be redundant if a non-opportunistic
         * negotiation is already being attempted.
         */

        /* We will only request an IPsec SA if policy isn't empty
         * (ignoring Main Mode items).
         * This is a fudge, but not yet important.
         * If we are to proceed asynchronously, whackfd will be NULL_FD.
         */

        passert(HAS_IPSEC_POLICY(c->policy));

#ifdef KLIPS
        if (held)
        {
            /* what should we do on failure? */
            (void) assign_hold(c, our_client, peer_client);
        }
#endif
        ipsecdoi_initiate(whackfd, c, c->policy, 1, SOS_NOBODY);
        whackfd = NULL_FD; /* protect from close */

...

-----------------------------------------------------------------------------------------------

/* Find an existing connection for a trapped outbound packet.
 * This is attempted before we bother with gateway discovery.
 * + this connection is routed (i.e. approved for on-demand)
 * + this subnet contains our_client (or we are our_client)
 * + that subnet contains peer_client (or peer is peer_client)
 * + don't care about Phase 1 IDs (we don't know)
 * + require that the connection HAS_IPSEC_POLICY (duh: to serve clients)
 * Give preference to the first one that has an SA (either phase).
 * Otherwise, give preference to one with highest routing.
 */
static struct connection *
find_connection_for_clients(const ip_address *our_client, const ip_address *peer_client)
{
    struct connection *c = connections
        , *best = NULL;

    passert(!isanyaddr(our_client) && !isanyaddr(peer_client));

    for (c = connections; c != NULL; c = c->ac_next)
    {
        if (HAS_IPSEC_POLICY(c->policy)
        && routed(c->routing)
        && addrinsubnet(our_client, &c->this.client)
        && addrinsubnet(peer_client, &c->that.client))
        {
            if ((best == NULL || best->routing <= c->routing))
                best = c;
            if (c->newest_isakmp_sa != SOS_NOBODY
            || c->newest_ipsec_sa != SOS_NOBODY)
                return c;
        }
    }
    return best;
}

bool
assign_hold(struct connection *c
, const ip_address *src, const ip_address *dst)
{
    /* either the automatically installed %hold eroute is broad enough
     * or we try to add a broader one and delete the automatic one.
     * Beware: this %hold might be already handled, but still squeak
     * through because of a race.
     */
    enum routing_t ro = c->routing /* routing, old */
        , rn = ro; /* routing, new */

    /* figure out what routing should become */
    switch (ro)
    {
    case RT_UNROUTED:
        rn = RT_UNROUTED_HOLD;
        break;
    case RT_ROUTED_PROSPECTIVE:
        rn = RT_ROUTED_HOLD;
        break;
    default:
        /* no change: this %hold is old news and should just be deleted */
        break;
    }

    if (subnetishost(&c->this.client) && subnetishost(&c->that.client))
    {
        /* although %hold is appropriately broad, it will no longer be bare
         * so we must ditch it from the bare table.
         */
        free_bare_shunt(bare_shunt_ptr(&c->this.client, &c->that.client));
    }
    else
    {
        /* we need a broad %hold, not the narrow one.
         * First we ensure that there is a broad %hold.
         * There may already be one (race condition): no need to create one.
         * There may already be a %trap: replace it.
         * There may not be any broad eroute: add %hold.
         * Once the broad %hold is in place, delete the narrow one.
         */
        if (rn != ro)
        {
            if (erouted(ro)
            ? !eroute_connection(c, htonl(SPI_HOLD), SA_INT, SADB_X_SATYPE_INT
                , ERO_REPLACE, "replace %trap with broad %hold")
            : !eroute_connection(c, htonl(SPI_HOLD), SA_INT, SADB_X_SATYPE_INT
                , ERO_ADD, "add broad %hold"))
            {
                return FALSE;
            }
        }
        if (!replace_bare_shunt(src, dst, SPI_HOLD, FALSE, c->this.protocol, c->addr_family, "delete narrow %hold"))
            return FALSE;
    }
    c->routing = rn;
    return TRUE;
}

-----------------------------------------------------------------------------------------------

/* Replace (or delete) a shunt that is in the bare_shunts table.
 * Issues the PF_KEY commands and updates the bare_shunts table.
 */
bool
replace_bare_shunt(const ip_address *src, const ip_address *dst
, ipsec_spi_t shunt_spi /* in host order! */
, bool repl, int transport_proto, sa_family_t af, const char *opname)
{
    ip_subnet this_client, that_client;
    const ip_address *null_host = aftoinfo(addrtypeof(src))->any;
    unsigned int op = repl? ERO_REPLACE : ERO_DELETE;

    passert(addrtypeof(src) == addrtypeof(dst));
    happy(addrtosubnet(src, &this_client));
    happy(addrtosubnet(dst, &that_client));

    if (raw_eroute(null_host, &this_client, null_host, &that_client
    , htonl(shunt_spi), SA_INT, transport_proto, af, SADB_X_SATYPE_INT, op, opname))
    {
        struct bare_shunt **bs_pp = bare_shunt_ptr(&this_client, &that_client);

        if (repl)
        {
            /* change over to new bare eroute */
            struct bare_shunt *bs = *bs_pp;

            bs->said.spi = htonl(shunt_spi);
            bs->said.proto = SA_INT;
            bs->said.dst = *null_host;
            bs->count = 0;
            bs->last_activity = now();
            DBG_bare_shunt("change", bs);
        }
        else
        {
            /* delete bare eroute */
            free_bare_shunt(bs_pp);
        }
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}

-----------------------------------------------------------------------------------------------

static bool
raw_eroute(const ip_address *this_host, const ip_subnet *this_client
, const ip_address *that_host, const ip_subnet *that_client
, ipsec_spi_t spi, unsigned int proto, unsigned int transport_proto
, sa_family_t af, unsigned int satype, unsigned int op
, const char *opname USED_BY_DEBUG)
{
    struct sadb_ext *extensions[SADB_EXT_MAX + 1];
    ip_address
        sflow_ska,
        dflow_ska,
        smask_ska,
        dmask_ska;
    char text_said[SATOT_BUF];
    unsigned short sport, dport;

    set_text_said(text_said, that_host, spi, proto);

    networkof(this_client, &sflow_ska);
    maskof(this_client, &smask_ska);
    sport = add_port_mask(af, &this_client->addr, &smask_ska);

    networkof(that_client, &dflow_ska);
    maskof(that_client, &dmask_ska);
    dport = add_port_mask(af, &that_client->addr, &dmask_ska);

    DBG(DBG_CONTROL | DBG_KLIPS,
        {
            char mybuf[SUBNETTOT_BUF];
            char peerbuf[SUBNETTOT_BUF];

            subnettot(this_client, 0, mybuf, sizeof(mybuf));
            subnettot(that_client, 0, peerbuf, sizeof(peerbuf));
            DBG_log("%s eroute %s:%d -> %s:%d => %s:%d"
                , opname, mybuf, ntohs(sport), peerbuf, ntohs(dport)
                , text_said, transport_proto);
        });

    return pfkey_msg_start(op & ERO_MASK, satype
        , "pfkey_msg_hdr flow", text_said, extensions)

    && (op == ERO_DELETE
        || (pfkey_build(pfkey_sa_build(&extensions[SADB_EXT_SA]
                , SADB_EXT_SA
                , spi /* in network order */
                , 0, 0, 0, 0, op >> ERO_FLAG_SHIFT)
            , "pfkey_sa add flow", text_said, extensions)

            && pfkeyext_address(SADB_EXT_ADDRESS_SRC, this_host
                , "pfkey_addr_s add flow", text_said, extensions)

            && pfkeyext_address(SADB_EXT_ADDRESS_DST, that_host
                , "pfkey_addr_d add flow", text_said, extensions)))

    && pfkeyext_address(SADB_X_EXT_ADDRESS_SRC_FLOW, &sflow_ska
        , "pfkey_addr_sflow", text_said, extensions)

    && pfkeyext_address(SADB_X_EXT_ADDRESS_DST_FLOW, &dflow_ska
        , "pfkey_addr_dflow", text_said, extensions)
    && pfkeyext_address(SADB_X_EXT_ADDRESS_SRC_MASK, &smask_ska
        , "pfkey_addr_smask", text_said, extensions)

    && pfkeyext_address(SADB_X_EXT_ADDRESS_DST_MASK, &dmask_ska
        , "pfkey_addr_dmask", text_said, extensions)

    && pfkeyext_protocol(transport_proto, "pfkey_x_protocol",
                         text_said, extensions)

    && finish_pfkey_msg(extensions, "flow", text_said, NULL);
}

_______________________________________________
Users mailing list
Users_at_lists.freeswan.org
http://lists.freeswan.org/mailman/listinfo/users



This archive was generated by hypermail 2.1.5 : Wed Jan 01 2003 - 05:21:05 CET