ikev1: Add an option to accept unencrypted ID/HASH payloads

Even in Main Mode, some Sonicwall boxes seem to send ID/HASH payloads in
unencrypted form, probably to allow PSK lookup based on the ID payloads. We
by default reject that, but accept it if the
charon.accept_unencrypted_mainmode_messages option is set in strongswan.conf.

Initial patch courtesy of Paul Stewart.
This commit is contained in:
Martin Willi 2014-04-14 14:42:27 +02:00
parent 4469e3d050
commit c4c9d291d2
2 changed files with 35 additions and 1 deletions

View File

@ -8,6 +8,21 @@ charon {}
**charon-cmd** instead of **charon**). For many options defaults can be
defined in the **libstrongswan** section.
charon.accept_unencrypted_mainmode_messages = no
Accept unencrypted ID and HASH payloads in IKEv1 Main Mode.
Accept unencrypted ID and HASH payloads in IKEv1 Main Mode.
Some implementations send the third Main Mode message unencrypted, probably
to find the PSKs for the specified ID for authentication. This is very
similar to Aggressive Mode, and has the same security implications: A
passive attacker can sniff the negotiated Identity, and start brute forcing
the PSK using the HASH payload.
It is recommended to keep this option to no, unless you know exactly
what the implications are and require compatibility to such devices (for
example, some SonicWall boxes).
charon.block_threshold = 5
Maximum number of half-open IKE_SAs for a single peer IP.

View File

@ -1922,6 +1922,24 @@ static status_t decrypt_and_extract(private_message_t *this, keymat_t *keymat,
return SUCCESS;
}
/**
* Do we accept unencrypted ID/HASH payloads in Main Mode, as seen from
* some SonicWall boxes?
*/
static bool accept_unencrypted_mm(private_message_t *this, payload_type_t type)
{
if (this->exchange_type == ID_PROT)
{
if (type == ID_V1 || type == HASH_V1)
{
return lib->settings->get_bool(lib->settings,
"%s.accept_unencrypted_mainmode_messages",
FALSE, lib->ns);
}
}
return FALSE;
}
/**
* Decrypt payload from the encryption payload
*/
@ -1978,7 +1996,8 @@ static status_t decrypt_payloads(private_message_t *this, keymat_t *keymat)
this->exchange_type != AGGRESSIVE)
{
rule = get_payload_rule(this, type);
if (!rule || rule->encrypted)
if ((!rule || rule->encrypted) &&
!accept_unencrypted_mm(this, type))
{
DBG1(DBG_ENC, "payload type %N was not encrypted",
payload_type_names, type);