diff --git a/conf/options/charon.opt b/conf/options/charon.opt index c6f4f1e9e..aaf4fdc14 100644 --- a/conf/options/charon.opt +++ b/conf/options/charon.opt @@ -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. diff --git a/src/libcharon/encoding/message.c b/src/libcharon/encoding/message.c index 11e735a37..3a1014ef0 100644 --- a/src/libcharon/encoding/message.c +++ b/src/libcharon/encoding/message.c @@ -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);