xpc: add support for initiate simple IKEv2 EAP connections
authorMartin Willi <martin@revosec.ch>
Fri, 26 Apr 2013 13:17:36 +0000 (15:17 +0200)
committerMartin Willi <martin@revosec.ch>
Thu, 18 Jul 2013 10:17:54 +0000 (12:17 +0200)
src/frontends/osx/charon-xpc/xpc_dispatch.c

index 3ade310..f9f4881 100644 (file)
@@ -58,6 +58,131 @@ static xpc_object_t get_version(private_xpc_dispatch_t *this,
 }
 
 /**
+ * Create peer config with associated ike config
+ */
+static peer_cfg_t* create_peer_cfg(char *name, char *host)
+{
+       ike_cfg_t *ike_cfg;
+       peer_cfg_t *peer_cfg;
+       u_int16_t local_port, remote_port = IKEV2_UDP_PORT;
+
+       local_port = charon->socket->get_port(charon->socket, FALSE);
+       if (local_port != IKEV2_UDP_PORT)
+       {
+               remote_port = IKEV2_NATT_PORT;
+       }
+       ike_cfg = ike_cfg_create(IKEV2, TRUE, FALSE, "0.0.0.0", FALSE, local_port,
+                                                        host, FALSE, remote_port, FRAGMENTATION_NO, 0);
+       ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
+       peer_cfg = peer_cfg_create(name, ike_cfg,
+                                                          CERT_SEND_IF_ASKED, UNIQUE_REPLACE, 1, /* keyingtries */
+                                                          36000, 0, /* rekey 10h, reauth none */
+                                                          600, 600, /* jitter, over 10min */
+                                                          TRUE, FALSE, /* mobike, aggressive */
+                                                          30, 0, /* DPD delay, timeout */
+                                                          FALSE, NULL, NULL); /* mediation */
+       peer_cfg->add_virtual_ip(peer_cfg, host_create_from_string("0.0.0.0", 0));
+
+       return peer_cfg;
+}
+
+/**
+ * Add a single auth cfg of given class to peer cfg
+ */
+static void add_auth_cfg(peer_cfg_t *peer_cfg, bool local,
+                                                char *id, auth_class_t class)
+{
+       auth_cfg_t *auth;
+
+       auth = auth_cfg_create();
+       auth->add(auth, AUTH_RULE_AUTH_CLASS, class);
+       auth->add(auth, AUTH_RULE_IDENTITY, identification_create_from_string(id));
+       peer_cfg->add_auth_cfg(peer_cfg, auth, local);
+}
+
+/**
+ * Attach child config to peer config
+ */
+static child_cfg_t* create_child_cfg(char *name)
+{
+       child_cfg_t *child_cfg;
+       traffic_selector_t *ts;
+       lifetime_cfg_t lifetime = {
+               .time = {
+                       .life = 10800 /* 3h */,
+                       .rekey = 10200 /* 2h50min */,
+                       .jitter = 300 /* 5min */
+               }
+       };
+
+       child_cfg = child_cfg_create(name, &lifetime,
+                                                                NULL, FALSE, MODE_TUNNEL, /* updown, hostaccess */
+                                                                ACTION_NONE, ACTION_NONE, ACTION_NONE, FALSE,
+                                                                0, 0, NULL, NULL, 0);
+       child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
+       ts = traffic_selector_create_dynamic(0, 0, 65535);
+       child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
+       ts = traffic_selector_create_from_string(0, TS_IPV4_ADDR_RANGE,
+                                                                               "0.0.0.0", 0, "255.255.255.255", 65535);
+       child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
+
+       return child_cfg;
+}
+
+/**
+ * Controller initiate callback
+ */
+static bool initiate_cb(u_int32_t *sa, debug_t group, level_t level,
+                                               ike_sa_t *ike_sa, const char *message)
+{
+       if (ike_sa)
+       {
+               *sa = ike_sa->get_unique_id(ike_sa);
+               return FALSE;
+       }
+       return TRUE;
+}
+
+/**
+ * Start initiating an IKE connection
+ */
+xpc_object_t start_connection(private_xpc_dispatch_t *this,
+                                                         xpc_object_t request, xpc_connection_t client)
+{
+       xpc_object_t reply;
+       peer_cfg_t *peer_cfg;
+       child_cfg_t *child_cfg;
+       char *name, *id, *host;
+       u_int32_t sa = 0;
+
+       name = (char*)xpc_dictionary_get_string(request, "name");
+       host = (char*)xpc_dictionary_get_string(request, "host");
+       id = (char*)xpc_dictionary_get_string(request, "id");
+       reply = xpc_dictionary_create_reply(request);
+
+       if (name && id && host)
+       {
+               peer_cfg = create_peer_cfg(name, host);
+
+               add_auth_cfg(peer_cfg, TRUE, id, AUTH_CLASS_EAP);
+               add_auth_cfg(peer_cfg, FALSE, host, AUTH_CLASS_ANY);
+
+               child_cfg = create_child_cfg(name);
+               peer_cfg->add_child_cfg(peer_cfg, child_cfg->get_ref(child_cfg));
+
+               if (charon->controller->initiate(charon->controller, peer_cfg, child_cfg,
+                                                       (controller_cb_t)initiate_cb, &sa, 0) != SUCCESS)
+               {
+                       sa = 0;
+               }
+       }
+
+       xpc_dictionary_set_uint64(reply, "connection", sa);
+
+       return reply;
+}
+
+/**
  * XPC command dispatch table
  */
 static struct {
@@ -66,6 +191,7 @@ static struct {
                                                        xpc_object_t request, xpc_connection_t client);
 } commands[] = {
        { "get_version", get_version },
+       { "start_connection", start_connection },
 };
 
 /**