]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
Act on RADIUS DAE Disconnect requests
authorMartin Willi <martin@revosec.ch>
Wed, 22 Feb 2012 12:49:06 +0000 (13:49 +0100)
committerMartin Willi <martin@revosec.ch>
Mon, 5 Mar 2012 17:06:13 +0000 (18:06 +0100)
src/libcharon/plugins/eap_radius/eap_radius_dae.c

index 7a678bb2aeaa0c372d608e2726765f11af89f4b4..8744b8b8340eb7f4e8314dc2f5910b0ff6d5c9d5 100644 (file)
@@ -72,6 +72,59 @@ struct private_eap_radius_dae_t {
        signer_t *signer;
 };
 
+/**
+ * Process a DAE disconnect request, send response
+ */
+static void process_disconnect(private_eap_radius_dae_t *this,
+               radius_message_t *request, struct sockaddr* addr, socklen_t addr_len)
+{
+       enumerator_t *enumerator, *sa_enum;
+       identification_t *user;
+       linked_list_t *ids;
+       uintptr_t id;
+       ike_sa_t *ike_sa;
+       chunk_t data;
+       host_t *host;
+       int type;
+
+       ids = linked_list_create();
+
+       host = host_create_from_sockaddr(addr);
+       enumerator = request->create_enumerator(request);
+       while (enumerator->enumerate(enumerator, &type, &data))
+       {
+               if (type == RAT_USER_NAME && data.len)
+               {
+                       user = identification_create_from_data(data);
+                       DBG1(DBG_CFG, "received RADIUS DAE %N for %Y from %H",
+                                radius_message_code_names, RMC_DISCONNECT_REQUEST, user, host);
+                       sa_enum = charon->ike_sa_manager->create_enumerator(
+                                                                                       charon->ike_sa_manager, FALSE);
+                       while (sa_enum->enumerate(sa_enum, &ike_sa))
+                       {
+                               if (user->matches(user, ike_sa->get_other_eap_id(ike_sa)))
+                               {
+                                       id = ike_sa->get_unique_id(ike_sa);
+                                       ids->insert_last(ids, (void*)id);
+                               }
+                       }
+                       sa_enum->destroy(sa_enum);
+                       user->destroy(user);
+               }
+       }
+       enumerator->destroy(enumerator);
+       DESTROY_IF(host);
+
+       enumerator = ids->create_enumerator(ids);
+       while (enumerator->enumerate(enumerator, &id))
+       {
+               charon->controller->terminate_ike(charon->controller, id, NULL, NULL, 0);
+       }
+       enumerator->destroy(enumerator);
+
+       ids->destroy(ids);
+}
+
 /**
  * Receive RADIUS DAE requests
  */
@@ -100,7 +153,9 @@ static job_requeue_t receive(private_eap_radius_dae_t *this)
                                switch (request->get_code(request))
                                {
                                        case RMC_DISCONNECT_REQUEST:
-                                               /* TODO */
+                                               process_disconnect(this, request,
+                                                                                  (struct sockaddr*)&addr, addr_len);
+                                               break;
                                        case RMC_COA_REQUEST:
                                                /* TODO */
                                        default: