-/**
- * Get the two auth classes from local or remote config
- */
-static void get_auth_class(peer_cfg_t *peer_cfg, bool local,
- auth_class_t *c1, auth_class_t *c2)
-{
- enumerator_t *enumerator;
- auth_cfg_t *auth;
-
- *c1 = *c2 = AUTH_CLASS_ANY;
-
- enumerator = peer_cfg->create_auth_cfg_enumerator(peer_cfg, local);
- while (enumerator->enumerate(enumerator, &auth))
- {
- if (*c1 == AUTH_CLASS_ANY)
- {
- *c1 = (uintptr_t)auth->get(auth, AUTH_RULE_AUTH_CLASS);
- }
- else
- {
- *c2 = (uintptr_t)auth->get(auth, AUTH_RULE_AUTH_CLASS);
- break;
- }
- }
- enumerator->destroy(enumerator);
-}
-
-/**
- * Get auth method to use from a peer config
- */
-static auth_method_t get_auth_method(private_main_mode_t *this,
- peer_cfg_t *peer_cfg)
-{
- auth_class_t i1, i2, r1, r2;
-
- get_auth_class(peer_cfg, this->initiator, &i1, &i2);
- get_auth_class(peer_cfg, !this->initiator, &r1, &r2);
-
- if (i1 == AUTH_CLASS_PUBKEY && r1 == AUTH_CLASS_PUBKEY)
- {
- if (i2 == AUTH_CLASS_ANY && r2 == AUTH_CLASS_ANY)
- {
- /* TODO-IKEv1: ECDSA? */
- return AUTH_RSA;
- }
- if (i2 == AUTH_CLASS_XAUTH)
- {
- return AUTH_XAUTH_INIT_RSA;
- }
- if (r2 == AUTH_CLASS_XAUTH)
- {
- return AUTH_XAUTH_RESP_RSA;
- }
- }
- if (i1 == AUTH_CLASS_PSK && r1 == AUTH_CLASS_PSK)
- {
- if (i2 == AUTH_CLASS_ANY && r2 == AUTH_CLASS_ANY)
- {
- return AUTH_PSK;
- }
- if (i2 == AUTH_CLASS_XAUTH)
- {
- return AUTH_XAUTH_INIT_PSK;
- }
- if (r2 == AUTH_CLASS_XAUTH)
- {
- return AUTH_XAUTH_RESP_PSK;
- }
- }
- if (i1 == AUTH_CLASS_XAUTH && r1 == AUTH_CLASS_PUBKEY &&
- i2 == AUTH_CLASS_ANY && r2 == AUTH_CLASS_ANY)
- {
- return AUTH_HYBRID_INIT_RSA;
- }
- return AUTH_NONE;
-}
-
-/**
- * Check if a peer skipped authentication by using Hybrid authentication
- */
-static bool skipped_auth(private_main_mode_t *this, bool local)
-{
- bool initiator;
-
- initiator = local == this->initiator;
- if (initiator && this->auth_method == AUTH_HYBRID_INIT_RSA)
- {
- return TRUE;
- }
- if (!initiator && this->auth_method == AUTH_HYBRID_RESP_RSA)
- {
- return TRUE;
- }
- return FALSE;
-}
-
-/**
- * Check if remote authentication constraints fulfilled
- */
-static bool check_constraints(private_main_mode_t *this)
-{
- identification_t *id;
- auth_cfg_t *auth;
-
- auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
- /* auth identity to comply */
- id = this->ike_sa->get_other_id(this->ike_sa);
- auth->add(auth, AUTH_RULE_IDENTITY, id->clone(id));
- if (skipped_auth(this, FALSE))
- {
- return TRUE;
- }
- return auth->complies(auth, this->other_auth, TRUE);
-}
-
-/**
- * Save authentication information after authentication succeeded
- */
-static void save_auth_cfg(private_main_mode_t *this, bool local)
-{
- auth_cfg_t *auth;
-
- if (skipped_auth(this, local))
- {
- return;
- }
- auth = auth_cfg_create();
- /* for local config, we _copy_ entires from the config, as it contains
- * certificates we must send later. */
- auth->merge(auth, this->ike_sa->get_auth_cfg(this->ike_sa, local), local);
- this->ike_sa->add_auth_cfg(this->ike_sa, local, auth);
-}
-
-/**
- * Select the best configuration as responder
- */
-static peer_cfg_t *select_config(private_main_mode_t *this, identification_t *id)
-{
- enumerator_t *enumerator;
- peer_cfg_t *current, *found = NULL;
- host_t *me, *other;
-
- me = this->ike_sa->get_my_host(this->ike_sa);
- other = this->ike_sa->get_other_host(this->ike_sa);
- DBG1(DBG_CFG, "looking for %N peer configs matching %H...%H[%Y]",
- auth_method_names, this->auth_method, me, other, id);
- enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends,
- me, other, NULL, id, IKEV1);
- while (enumerator->enumerate(enumerator, ¤t))
- {
- if (get_auth_method(this, current) == this->auth_method)
- {
- found = current->get_ref(current);
- break;
- }
- }
- enumerator->destroy(enumerator);
-
- if (found)
- {
- DBG2(DBG_CFG, "selected peer config \"%s\"", found->get_name(found));
- }
- return found;
-}
-